1.Executors
Executors是类似Collections和Arrays一样的工具类,包含了很多静态工厂方法来生产常用线程池。
常用静态工厂方法:
// 创建一个指定大小的线程池,返回ThreadPoolExecutor的实现
public static ExecutorService newFixedThreadPool(int nThreads);
// 创建一个按需创建、回收线程的线程池,返回ThreadPoolExecutor的实现
public static ExecutorService newCachedThreadPool();
// 创建一个能定时执行任务的线程池,周期执行
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize);
// 创建一个只包含一个线程的线程池,保证串行执行任务,同时刻仅有一个任务在执行
public static ExecutorService newSingleThreadExecutor();
以上常用的线程池都返回ThreadPoolExecutor或ThreadPoolExecutor的子类ScheduledThreadPoolExecutor、代理类。
2.ThreadPoolExecutor
ThreadPoolExecutor 是Executor的基本实现
构造如下,以上的常用线程池都是改变了一些构造参数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue);
corePoolSize:线程池基本大小
maximumPoolSize:线程池最大大小
keepAliveTime:线程存活时间,空间时间**>keepAliveTime则标记为可回收
unit:时间单位,枚举可设置为秒、毫秒等
workQueue:工作队列
如newFixedThreadPool** 设置corePoolSize=maximumPoolSize=参数***nThreads***
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
newCachedThreadPool设置corePoolSize=1,maximumPoolSize=Integer.MAX_VALUE
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
3.ScheduledThreadPoolExecutor
返回ScheduledThreadPoolExecutor ,是ThreadPoolExecutor的子类
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue());
}
主要区别是工作队列是DelayedWorkQueue,是个基于堆的数据结构,
初始堆、添加到堆,会按照任务的延时时间进行排序,延时时间少的任务首先被获取。
获取堆顶take()时会判断堆顶任务的延迟时间有没有到,如果到了则返回该任务;
如果没到,堆顶任务等待delay时间。
4.使用Example
newFixedThreadPool
@Test
public void testExecutors() {
int nthreads = 2;
ExecutorService pool = Executors.newFixedThreadPool(nthreads);
for (int i = 0;i < nthreads; i++) {
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().toString());
}
});
}
}
newScheduledThreadPool
scheduleAtFixedRate 周期定时执行任务
/**
* 定时任务
* firstExecuteTime = curTime + initialDelay 第二个参数决定首次执行时间
* scheduledExecutionTime(第n次)=firstExecuteTime +n*periodTime 第三个参数决定周期时间
* @throws Exception
*/
@Test
public void scheduleTest() throws Exception{
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService.scheduleAtFixedRate(new PrintCommand(), 1,1,TimeUnit.SECONDS);
// Thread.currentThread().join();
try {
boolean loop = true;
do { //等待线程池任务完成
loop = !executorService.awaitTermination(2, TimeUnit.SECONDS); //阻塞,直到线程池里所有任务结束
} while(loop);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
class PrintCommand implements Runnable {
public void run() {
System.out.println(Thread.currentThread().toString()+ " curtime: " + DateUtil.formatCurrent(DateUtil.TIME_FORMAT));
}
}
执行结果可见,每秒执行一次