?和??中的示例都存在一个重要的缺陷,它们要求您直接创建?Thread
?对象。这可以解决一些问题,因为在一些 JVM 中,创建Thread
?是一项重量型的操作,重用现有?Thread
?比创建新线程要容易得多。而在另一些 JVM 中,情况正好相反:Thread
?是轻量型的,可以在需要时很容易地新建一个线程。当然,如果 Murphy 拥有自己的解决办法(他通常都会拥有),那么您无论使用哪种方法对于您最终将部署的平台都是不对的。
JSR-166 专家组(参见?)在一定程度上预测到了这一情形。Java 开发人员无需直接创建?Thread
,他们引入了?Executor
?接口,这是对创建新线程的一种抽象。如清单 3 所示,Executor
?使您不必亲自对?Thread
?对象执行?new
?就能够创建新线程:
使用?Executor
?的主要缺陷与我们在所有工厂中遇到的一样:工厂必须来自某个位置。不幸的是,与 CLR 不同,JVM 没有附带一个标准的 VM 级线程池。
Executor
?类实际上?充当着一个提供?Executor
?实现实例的共同位置,但它只有?new
?方法(例如用于创建新线程池);它没有预先创建实例。所以您可以自行决定是否希望在代码中创建和使用?Executor
?实例。(或者在某些情况下,您将能够使用所选的容器/平台提供的实例。)
尽管不必担心?Thread
?来自何处,但?Executor
?接口缺乏 Java 开发人员可能期望的某种功能,比如结束一个用于生成结果的线程并以非阻塞方式等待结果可用。(这是桌面应用程序的一个常见需求,用户将执行需要访问数据库的 UI 操作,然后如果该操作花费了很长时间,可能希望在它完成之前取消它。)
对于此问题,JSR-166 专家创建了一个更加有用的抽象(ExecutorService
?接口),它将线程启动工厂建模为一个可集中控制的服务。例如,无需每执行一项任务就调用一次?execute()
,ExecutorService
?可以接受一组任务并返回一个表示每项任务的未来结果的未来列表。
尽管?ExecutorService
?接口非常有用,但某些任务仍需要以计划方式执行,比如以确定的时间间隔或在特定时间执行给定的任务。这就是ScheduledExecutorService
?的应用范围,它扩展了?ExecutorService
。
如果您的目标是创建一个每隔 5 秒跳一次的 “心跳” 命令,使用?ScheduledExecutorService
?可以轻松实现,如清单 4 所示:
public class Ping
{
public static void main(String[] args)
{
ScheduledExecutorService ses =
Executors.newScheduledThreadPool(1);
Runnable pinger = new Runnable() {
public void run() {
System.out.println("PING!");
}
};
ses.scheduleAtFixedRate(pinger,5,TimeUnit.SECONDS);
}
}
这项功能怎么样?不用过于担心线程,不用过于担心用户希望取消心跳时会发生什么,也不用明确地将线程标记为前台或后台;只需将所有的计划细节留给?ScheduledExecutorService
。
顺便说一下,如果用户希望取消心跳,scheduleAtFixedRate
?调用将返回一个?ScheduledFuture
?实例,它不仅封装了结果(如果有),还拥有一个?cancel
?方法来关闭计划的操作。
为阻塞操作设置一个具体的超时值(以避免死锁)的能力是?java.util.concurrent
?库相比起早期并发特性的一大进步,比如监控锁定。
这些方法几乎总是包含一个?int
/TimeUnit
?对,指示这些方法应该等待多长时间才释放控制权并将其返回给程序。它需要开发人员执行更多工作 — 如果没有获取锁,您将如何重新获取? — 但结果几乎总是正确的:更少的死锁和更加适合生产的代码。(关于编写生产就绪代码的更多信息,请参见??中 Michael Nygard 编写的?Release It!。)
java.util.concurrent
?包还包含了其他许多好用的实用程序,它们很好地扩展到了 Collections 之外,尤其是在?.locks
?和?.atomic
?包中。深入研究,您还将发现一些有用的控制结构,比如?CyclicBarrier
?等。
与 Java 平台的许多其他方面一样,您无需费劲地查找可能非常有用的基础架构代码。在编写多线程代码时,请记住本文讨论的实用程序和??中讨论的实用程序。
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!