「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战」@[toc]
六.四个常用的线程池:
①.Executors
使用:package java.util.concurrent 中的 Executors类,通过Executors类的静态方法,可以创建出我们常用的几个线程池;
复制代码
②.使用Executors创建线程池
1.cachedThreadPool
可缓存线程池
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
复制代码
可以看到发生了重载,第二个方法里加入了参数ThreadFactory
使用时:
ExecutorService CachedThreadPool = Executors.newCachedThreadPool();
ExecutorService CachedThreadPool = Executors.newCachedThreadPool(threadFactory);
复制代码
根据我们上面对ThreadPoolExecutor类的分析,这里是返回了一个
corePoolSize为0,maximumPoolSize(池中允许的最大线程数)为2^31-1个,keepAliveTime(空闲线程等待时间)为60秒,创建一个非公平竞争的队列
2.FixedThreadPool
可重用固定个数的线程池
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
复制代码
可以看到发生了重载,第二个方法里加入了参数ThreadFactory
使用时:
ExecutorService FixedThreadPool = Executors.newFixedThreadPool(int);
ExecutorService FixedThreadPool = Executors.newFixedThreadPool(int,threadFactory);
复制代码
根据我们上面对ThreadPoolExecutor类的分析,这里是返回了一个
corePoolSize和maximumPoolSize(池中允许的最大线程数)的个数都为传入的nThreads值,keepAliveTime(空闲线程等待时间)为0毫秒,创建一个容量为2^31-1大小的Lind阻塞队列
3.ScheduledThreadPool
创建一个线程池,该线程池可以安排命令在给定延迟后运行或定期执行。@param corePoolSize保留在线程池中的线程数,即使它们是空闲的
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
复制代码
使用时:(demo)
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
/**
* 创建并执行在给定延迟后启用的一次性操作
*/
scheduledExecutorService.schedule(new Runnable() {
@Override
public void run() {
System.out.println("10秒延迟结束");
}
},10,TimeUnit.SECONDS);
/**
*创建并执行一个周期性动作,该动作在给定的初始延迟之后首先启用,然后在给定的周期之后启用;即执行将在{@code initialDelay}之后开始,然后是{@code *initialDelay+period},然后是{@code initialDelay+ 2 period},以此类推。如果任务的任何执行遇到异常,则禁止后续执行。否则,任务只能通过取 *消或终止执行器来终止。如果该任务的任何执行花费的时间超过了它的周期,那么后续执行可能会延迟开始,但不会并发执行。
*/
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
{任务}
}
},1,3,TimeUnit.SECONDS);
复制代码
4.SingleThreadExecutor
创建一个Executor,该Executor使用一个工作线程操作一个无界队列。任务保证按顺序执行(但是请注意,如果这个线程在关闭之前的执行过程中由于失败而终止,如果需要执行后续任务,将会有一个新的线程代替它。),与等价的{@code newFixedThreadPool(1)}不同,返回的执行器保证不会被重新配置以使用其他线程
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
复制代码
可以看到发生了重载,第二个方法里加入了参数ThreadFactory
关键的是被FinalizableDelegatedExecutorService修饰了,可以确保它一旦被创建,始终保持单线程。
近期评论