JAVA8的5种线程池
介绍
JAVA1.8版本加了一种newWorkStealingPool,现在共有5种线程池:newSingleThreadPool、newFixedThreadPool、newCachedThreadPool、newScheduledThreadPool、newWorkStealingPool。
参考:https://vvcat.blog.csdn.net/article/details/91409942
线程池的创建步骤:
//创建单核心的线程池
ExecutorService executorService = Executors.newSingleThreadExecutor();
//创建固定核心数的线程池,这里核心数 = 2
ExecutorService executorService = Executors.newFixedThreadPool(2);
//创建一个按照计划规定执行的线程池,这里核心数 = 2
ExecutorService executorService = Executors.newScheduledThreadPool(2);
//创建一个自动增长的线程池
ExecutorService executorService = Executors.newCachedThreadPool();
//创建一个具有抢占式操作的线程池
ExecutorService executorService = Executors.newWorkStealingPool();
线程池的参数:
- corePoolSize:核心线程数,当初始化线程池时,会创建核心线程进入等待状态,即使它是空闲的,核心线程也不会被摧毁,从而降低了任务一来时要创建新线程的时间和性能开销;
- maximumPoolSize:最大线程数,核心线程数都被用完了,那只能重新创建新的线程来执行任务,但是前提是不能超过最大线程数量;
- keepAliveTime:线程存活时间,除核心线程外被创建的线程可以存活多久,即这些线程完成任务,后面处于空闲状态,一定时间后被销毁;
- unit:存活时间单位;
- workQueue:任务的阻塞队列,未被执行的任务需要进入队列中排队,队列是FIFO的,等到线程空闲时,再取出里面的任务;
newSingleThreadPool
单核心线程池,最大线程数只会有一个,时间为0表示无限的生命,不会被销毁;
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
newFixedThreadPool
核心线程数固定,需要在创建时传入,并且核心线程数就是最大线程数,存活时间无限,不会销毁;
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
newCachedThreadPool
可进行缓存的线程池,常用的线程池。它的线程数是无限的,核心线程数为0,默认是存活时间是60s,即空闲60s后被销毁。有2种创建方法:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
效果:当线程池中没有空闲线程时,这时有任务过来了,那么会新建线程执行任务。有空闲线程则会复用;
newScheduledThreadPool
有计划性的线程池,可设置延迟时间,在给定的延迟时间之后运行,或者周期性的运行。与Timer定时器类似。构造函数:
/**
* Creates a new {@code ScheduledThreadPoolExecutor} with the
* given core pool size.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @throws IllegalArgumentException if {@code corePoolSize < 0}
*/
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
内部用的延时阻塞队列维护任务进行,线程池并不常用。
newWorkStealingPool
抢占式线程池,与其他4种不同,使用的是ForkJoinPool类,构造函数:
/**
* Creates a thread pool that maintains enough threads to support
* the given parallelism level, and may use multiple queues to
* reduce contention. The parallelism level corresponds to the
* maximum number of threads actively engaged in, or available to
* engage in, task processing. The actual number of threads may
* grow and shrink dynamically. A work-stealing pool makes no
* guarantees about the order in which submitted tasks are
* executed.
*
* @param parallelism the targeted parallelism level
* @return the newly created thread pool
* @throws IllegalArgumentException if {@code parallelism <= 0}
* @since 1.8
*/
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
它是一个并行的线程池,入参是线程并发的数量,这个线程不会保证任务的顺序执行,哪个线程抢到任务,就由它执行