J2SE 5.0平台包含了一个新的并发工具程序包。这个程序包中的类替并发类(concurrent classe)或并发设计中使用的应用程序建立阻塞(blocking)。该并发工具包含下面一些内容:
高性能的、灵活的线程池
异步执行事务的框架组件
为并发访问优化过的集合类宿主(host)
本文介绍了J2SE 5.0框架组件类和它们的重要特性。本文的下载代码提供了一些简单的、容易使用的示例,它演示了所有的新线程框架组件类。你在阅读文章内容之后运行这些示例可以使自己对这些特性有更好的理解。
Executor(执行器)框架组件
Executor框架组件提供了一个简单的、标准的、可扩充的类,它提供了一些有用的功能,如果没有这些功能,我们要手工实现这些它们,会觉得十分单调和困难。该框架组件使调用、调度和执行的操作标准化了。它通过一组执行策略为控制异步事务提供了支持。
Executor接口执行已提交的可以运行的事务。它提供了一条途径,允许我们把事务提交从事务执行机制中分离出来。程序员通常使用Executor代替显式地(explicitly)建立线程。Executor接口也提供事务的同步和异步执行。
对于同步执行,使用下面的命令:
Class MySynExecutor implements Executor{
public void execute(Runnable r) {
r.run();
}
}
对于异步执行,使用下面的命令:
Class MyASynExecutor implements Executor{
public void execute(Runnable r) {
new Thread(r).start();
}
}
ExecutorService(执行器服务)类
ExecutorService类为管理一个或多个异步事务的终止和跟踪事务执行的过程提供了方法。代码下载中的MyExecutorService.java文件演示了管理事务终止的过程。它初始化了大小为三个的线程池,然后依次添加了线程。当线程的数量达到线程池的大小限制时,它调用关闭(shutdown)方法。在调用shutdown()方法之后,这个线程池不再接受新事务的执行。在等待十秒以后,该线程池调用shutDownNow()。这个方法会尽最大的努力来终止所有运行中的事务。在示例中,应用程序试图终止运行中的线程失败了。
ScheduledExecutorService(调度执行器服务)
ScheduledExecutorService类是我的最喜欢的类。它对于调度那些周期性执行的事务非常方便,而周期性执行的事务对于清除工作(例如清除你的应用程序建立的临时文件等等)尤其有用。下载代码中的MyScheduledExecutorService.java文件通过每五秒钟发出"嘟嘟"一声演示了调度的过程:
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture beeperHandle =scheduler.scheduleAtFixedRate(beeper, 1, 5, SECONDS);
Future和FutureTask
在Java的早期版本中,查询运行中的线程状态,以及使线程在执行之后返回一个值是非常困难的。由于run(运行)方法返回void,你必须编写大量的代码从线程中返回一个值。使用过这种方法的程序员肯定了解其痛苦的经历。
你可以使用Future接口或者FutureTask类从异步执行的线程中得到一个返回值。Future接口提供了检查计算过程是否完成、检索计算结果或终止计算过程的一些方法。FutureTask类提供了Future接口方法的基本实现(implementation)。只有计算过程完成以后才能检索结果;如果计算过程没有完成,get方法会被阻塞(block)。
下载代码中的MyStringReverser.java文件演示了FutureTask类的使用,并提供了一个容易理解的示例。它以每秒钟一个字符的速度从后向前显示提交的字符串,同时主线程检测事务是否完成了:
while(!future.isDone()){
System.out.println("Task not yet completed.");
try{
Thread.currentThread().sleep(500);
}catch(InterruptedException ie){
System.out.println("Will check after 1/2 sec.");
}
}
在事务完成以后,就使用get方法从Future对象中检索结果:
System.out.println("Here is result..."+future.get());
ThreadPoolExecutor(线程池执行器)