Executors静态工厂创建几种常用线程池
- Executors类:
提供工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口;
1.创建了一个固定线程数量的线程池,可以控制线程最大并发数,超出的线程会在队列中等待。
它是一个典型且优秀的线程池,它具有线程池提高程序效率和节省创建线程时所耗的开销的优点。但是在线程池空闲时,即线程池中没有可运行任务时,它也不会释放工作线程,还会占用一定的系统资源。
newFixedThreadPool(int nThreads)
//线程池中线程数量是要指定传入的,注意在固定大小的线程池中使用的阻塞队列是LinkedBlockingQueue,无界阻塞队列。
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);
}
2.创建了一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有的任务按照指定的顺序(FIFO, LIFO, 优先级)来执行的。
初始化的线程池中只有一个线程,如果该线程异常结束,会重新创建一个新的线程继续执行任务,唯一的线程可以保证所提交任务的顺序执行,内部使用LinkedBlockingQueue作为阻塞队列
newSingleThreadExecutor()
//核心线程数和最大线程数都为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));
}
3.创建了一个可缓存的线程池,如果线程池的长度超过处理需要,它可灵活回收空闲线程,若无可回收,则新建线程。
默认存活时间60秒,线程池的线程数可达到Integer.MAX_VALUE,即2147483647,内部使用SynchronousQueue作为阻塞队列;新增一个任务即有一个线程处理,或者复用之前空闲的线程,或者重亲启动一个线程,但是一旦一个线程在60秒内一直处于等待状态时(也就是一分钟无事可做),则会被终止
在没有任务执行时,当线程的空闲时间超过keepAliveTime,则工作线程将会终止,当提交新任务时,如果没有空闲线程,则创建新线程执行任务,会导致一定的系统开销
newCachedThreadPool()
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);
}
4.创建了一个单线程的定时任务调度线程池
newSingleThreadScheduledExecutor()
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1, threadFactory));
}
5.创建了一个定长线程池,支持定时及周期性的任务执行。(定时调度线程池)
初始化的线程池可以在指定的时间内周期性的执行所提交的任务,在实际的业务场景中可以使用该线程池定期的同步数据。
newScheduledThreadPool(int corePoolSize)
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
- Demo实例:
(1)newFixedThreadPoolDemo:
public static void newFixedThreadPoolDemo(){
//创建一个固定长度的线程池,一次执行固定长度的线程,之后按照程序继续执行
ExecutorService fixedthreadpool = Executors.newFixedThreadPool(5);
System.out.println("fixedthreadpool is starting");
for (int i = 0; i < 15; i++) {
final int count = i ;
fixedthreadpool.execute(new Runnable() {
@Override
public void run() {
System.out.println(count +" " +Thread.currentThread().getName());
}
});
}
//shutdown方法只是发出了停止信号,
// 等所有线程执行完毕会关闭线程池;而shutdownNow则是立即停止所有任务。
fixedthreadpool.shutdown();
}
fixedthreadpool is starting
1 pool-1-thread-2
5 pool-1-thread-2
6 pool-1-thread-2
7 pool-1-thread-2
8 pool-1-thread-2
9 pool-1-thread-2
10 pool-1-thread-2
0 pool-1-thread-1
11 pool-1-thread-2
13 pool-1-thread-2
14 pool-1-thread-2
12 pool-1-thread-1
3 pool-1-thread-4
2 pool-1-thread-3
4 pool-1-thread-5
这是创建一个指定数量线程的线程池,使用newFixedThreadPool方法传入5个线程个数,从结果也可以看出是5个线程在并发执行,注意返回类型是ExecutorService。还使用了execute()方法提交线程。
(2)newSingleThreadExecutorDemo:
//创建单线程的线程池,一个一个线程的执行
public static void newSingleThreadExecutorDemo(){
ExecutorService singlethreadpool = Executors.newSingleThreadExecutor();
System.out.println("singlethreadpool is starting");
for (int i = 0; i < 10; i++) {
final int count = i ;
singlethreadpool.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(count +" " +Thread.currentThread().getName());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
单线程的线程池,只有一个线程在执行。
(3)newCachedThreadPoolDemo:
//创建一个可缓存的线程池 当线程池长度超过所需要的长度,则会收起空闲线程
public static void newCachedThreadPoolDemo(){
ExecutorService cachedthreadpool = Executors.newCachedThreadPool();
System.out.println("cachedthreadpool is starting");
for (int i = 0; i < 100; i++) {
final int count = i ;
cachedthreadpool.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(count + " " + Thread.currentThread().getName());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
(4)newSecheduledThreadPoolDemo:
//周期性的
public static void newSecheduledThreadPoolDemo() {
ExecutorService secheduledthreadpool = Executors.newScheduledThreadPool(5);
System.out.println("secheduledthreadpool is starting");
((ScheduledExecutorService) secheduledthreadpool).schedule(new Runnable() {
@Override
public void run() {
System.out.println("延时执行");
}
}, 3, TimeUnit.SECONDS);
方法注意:
ScheduledExecutorService#scheduleAtFixedRate()指的是“以固定的频率”执行,period(周期)指的是两次成功执行之间的时间;
ScheduledExecutorService#scheduleWithFixedDelay() 指的是“以固定的延时”执行,delay(延时)指的是一次执行终止和下一次执行开始之间的延迟;