概述
线程池就比如是一个装线程的池子,里面存在很大创建时就创建好的线程 创建的线程池要手动关闭,否则线程池里面的线程一直处于空闲,等待任务 线程池在启动的时,会创建大量空闲线程,当我们向线程池提交任务的时,线程池就会启动一个线程来执行该任务。等待任务执行完毕以后,线程并不会死亡,而是再次返回到线程池中称为空闲状态。等待下一次任务的执行。
创建线程池的方式
一、用Executors类的静态方法
static ExecutorService newCachedThreadPool() :创建一个默认的线程池,默认为认最多可以容纳int类型的最大值。 注意:创建一个线程池,根据需要创建新线程,但在可用时将重用先前构造的线程。 这些池通常会提高执行许多短期异步任务的程序的性能。 如果可用,调用execute将重用先前构造的线程。 如果没有可用的现有线程,则会创建一个新线程并将其添加到池中。 60 秒内未使用的线程将被终止并从缓存中删除。 因此,保持空闲足够长时间的池不会消耗任何资源。 static newFixedThreadPool(int nThreads) 创建一个指定最多线程数量的线程池 注意:创建一个线程池,该线程池重用固定数量的线程在共享的无界队列中运行。 在任何时候,最多nThreads线程将是活动的处理任务。 如果在所有线程都处于活动状态时提交了其他任务,它们将在队列中等待,直到有线程可用。 如果任何线程在关闭前的执行过程中因失败而终止,则在需要执行后续任务时,将有一个新线程取代它。 池中的线程将一直存在,直到它被明确shutdown 代码示例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
public static void main(String[] args) throws InterruptedException {
//1.创建默认数量的线程池
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(()->{
System.out.println("线程1");
});
executorService.submit(() -> {
System.out.println("线程2");
});
//关闭线程池
executorService.shutdown();
//2.创建指定上限的线程池
ExecutorService executorService2 = Executors.newFixedThreadPool(2);
ThreadPoolExecutor pool = (ThreadPoolExecutor) executorService2;
//返回池中的当前线程数
System.out.println("当前线程数"+pool.getPoolSize());
executorService2.submit(() -> {
System.out.println("线程a");
});
executorService2.submit(() -> {
System.out.println("线程b");
});
executorService2.submit(() -> {
System.out.println("线程c");
});
System.out.println("当前线程数"+pool.getPoolSize());
//关闭线程池
executorService2.shutdown();
}
}
结果
二、new ThreadPoolExecutor()创建线程池对象
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(核心线程数量,最大线程数量,空闲线程最大存活时间,任务队列,创建线程工厂,任务的拒绝策略); 其构造方法:public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) 使用给定的初始参数创建一个新的ThreadPoolExecutor 。
参数: corePoolSize – 要保留在池中的线程数,即使它们处于空闲状态,除非设置了allowCoreThreadTimeOut maximumPoolSize – 池中允许的最大线程数 keepAliveTime – 当线程数大于核心数时,这是多余空闲线程在终止前等待新任务的最长时间。 unit – keepAliveTime参数的时间单位 workQueue – 用于在执行任务之前保存任务的队列。 这个队列将只保存execute方法提交的Runnable任务。 threadFactory – 执行程序创建新线程时使用的工厂 handler – 执行被阻塞时使用的处理程序,因为达到了线程边界和队列容量,有四个子类
1. ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。是默认的策略。
2. ThreadPoolExecutor.DiscardPolicy: 丢弃任务,但是不抛出异常 这是不推荐的做法。
3. ThreadPoolExecutor.DiscardOldestPolicy: 抛弃队列中等待最久的任务 然后把当前任务加入队列中。
4. ThreadPoolExecutor.CallerRunsPolicy: 调用任务的run()方法绕过线程池直接执行。
注意:线程池对多可执行的任务数 = 队列容量 + 最大线程数 代码
import java.util.concurrent.*;
public class Test {
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1 , 3 , 20 ,
TimeUnit.SECONDS ,
new ArrayBlockingQueue<>(1) , Executors.defaultThreadFactory() , new
ThreadPoolExecutor.AbortPolicy()) ;
// 提交5个任务,而该线程池最多可以处理4个任务,当我们使用AbortPolicy这个任务处理策略的时候,就会抛出异常
for(int x = 0 ; x < 5 ; x++) {
threadPoolExecutor.submit(() -> {
System.out.println(Thread.currentThread().getName() + "---->> 执行了任务");
});
//停止1s则会每个任务正常,因为任务完成了不占用里面的线程‘
//Thread.sleep(1000);
}
}
}
结果