前言
上一章其实是介绍了ThreadPoolExecutor
中的addWorker()
方法,解析该方法我们了解了ThreadPoolExecutor
添加新任务的一整套流程:判断线程池是否处于Running
状态,因为SHUTDOWN
下的线程池是不能添加任务的,而后更新线程池内的线程数并于corePoolSize
比较,接着才能添加任务。Worker
是实现了Runnable
接口的。
execute()
与submit()
的区别
execute()
方法用于执行不需要返回结果的任务,因此execute()
之后我们无从得知任务是否被线程池成功执行,而submit()
则会返回一个实现了Future
接口的对象(也就是FutureTask
),通过这个对象就可以判断任务执行成功与否。
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
//其中依然会调用execute()来执行任务
关于FutureTask
,它实现了RunnableFuture
接口,然后RunnableFuture
又继承Runnable
和Future
接口。我们可以通过FutureTask
实例的get()
方法获取返回值,调用get()
时会阻塞当前线程直至任务完成,而调用
get(long timeout,TimeUnit unit)
则会阻塞当前线程一段时间后立即返回,即使任务还没有执行完。此外,调用FutureTask
对象的cancel(boolean mayInterruptIfRunning)
方法可以取消任务的执行。
ThreadPoolExecutor与ScheduledThreadPoolExecutor实例
/**
* 使用ScheduledExecutorService和ScheduledThreadPoolExecutor实现的java调度程序示例程序。
*/
public class ScheduledThreadPoolDemo {
public static void main(String[] args) throws InterruptedException {
//创建一个ScheduledThreadPoolExecutor对象
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
//计划在某段时间后运行
System.out.println("Current Time = "+new Date());
for(int i=0; i<3; i++){
Thread.sleep(1000);
WorkerThread worker = new WorkerThread("do heavy processing");
//创建并执行在给定延迟后启用的单次操作。
scheduledThreadPool.schedule(worker, 10, TimeUnit.SECONDS);
}
//添加一些延迟让调度程序产生一些线程
Thread.sleep(30000);
System.out.println("Current Time = "+new Date());
//关闭线程池
scheduledThreadPool.shutdown();
while(!scheduledThreadPool.isTerminated()){
//等待所有任务完成
}
System.out.println("Finished all threads");
}
}