Java 5中引入了并发包(java.util.concurrent),大大简化了多线程并发程序的开发。接下来我们分析一下引入concurrent包为多线程并发程序带来的变化。为清晰期间,进行对比说明。
第一,任务与调度框架
1,Timer和TimerTask
Java 1.3引入了java.util.Timer和java.util.TimerTask,TimerTask定义一个执行任务,而Timer则是一个简单的任务调度器。
示例(每10秒钟打印一下当前的系统时间)如下:
| TimerTask printClockTask = new TimeTask(){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public void run(){ System.out.println(sdf.format(new Date())); } }; Timer timer = new Timer(); //每10秒钟执行一次printClockTask,调度马上执行 timer.schedule(printClockTask, 0, 10000); |
撤销调度任务,可以调用cancel方法:
| timer.cancel(); // 注意 cancel内部会调用Thread的interrupt方法 |
2,ExecutorService
但是在JDK5之后,ExecutorService是Java 5引入的并发包中任务调度的接口。ExecutorService是任务调度器,可以调度执行实现了Runnable接口或Callable接口的任务。
简便的获得ExecutorService方法有如下3种:
| 单线程调度 | ExecutorService oneThreadExecutor = Executors.newSingleThreadExecutor(); |
| 固定线程数的线程池调度 | ExecutorService fixedPoolExecutor = Executors.newFixedThreadPool(5); |
| 不限数量缓存线程池调度 | ExecutorService unboundedPoolExecutor = Executors.newCachedThreadPool(); |
| 带调度周期的调度 | ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(1); |
其他高级的带配置参数的可以通过查看Executors的API了解到。
ExecutorService的使用也比较简单,对于不需要返回值的,直接调用:
| Runnable task = ...//构建任务 fixedPoolExecutor.execute(task); |
有返回值的:
| Callable<MyReturnType> task = ...//构建返回类型是MyReturnType的任务 Future<MyReturnType> future = fixedPoolExecutor.submit(task); MyReturnType result = future.get();//此方法通常堵塞到task执行完毕后,此方法也可以在其他线程中调用 |
无返回值的也可以使用submit,传递Runnable接口的实现实例,另外Future还可以对任务进行cancel。
未完待续...




