大多数服务端应用程序都需要同时处理任务的能力,这样可以提高工作性能并增加硬件资源的利用。在早期的Java版本(1.4或更早的)中,开发者需要完成并发(concurrent)应用程序——包括线程池逻辑—他们自己使用的是低层次语言结构和Java Thread API。但是结果却总是不理想。Java Thread API的特性会导致不知情的编程者开发一些难以调试的编程错误的代码。
在Java5.0中,Sun公司采用了Java concurrency功能(JSR-166)来解决这些问题,并且提供了一套标准的APIs来创建并开发应用程序。本文探究了一些Java concurrency package提供的特性并使用这些功能来演示编写并发应用程序的技术。
Concurrent Programming的挑战
自从它发布以来,Java就提供了Thread类和低层次语言结构,例如synchronized 和volatile用来开发独立平台的并发应用程序。但是,用这些特性来构建并发应用程序并不是简单的事情。开发者要面对以下的挑战:
不正确的编程会导致一些困境,就是两个或两个以上的线程都等待永远被锁住的对方。
在Java语言中没有机制用于写wait-free, lock-free算法。开发者必须使用本地代码。
开发者必须编写他们复杂的线程池逻辑,这样会很棘手并且容易出错。
Java Concurrency Utilities的概述
JSR-166(Java concurrency utilities),是Java5.0的一部分,通过着重在宽度并提供跨域大范围并发编程风格的重要功能,大大简化了在Java中并发应用程序的开发。
Java concurrency utilities提供了多种功能,开发者可以应用于更快更有预见性的并发应用程序的开发。这些功能让开发者从通过写自定义代码来重新发明wheel中解放出来。一些JSR-166的最显著的特点是:
标准的接口和构架来定义自定义线程子系统。
是一种机制用于规范调用,时序安排,执行和异步任务的控制,这是根据在Executor构架中的一套执行政策。
是一种机制通过类用于线程协调,例如semaphore, mutexe, barrier, latche和 exchangers。
非阻碍FIFO列队执行(ConcurrentLinkedQueue类)用于可升级的,有效的线程安全操作。
阻碍列队执行类来涵盖最常见的使用情况,对于生成者/消费者方法,信息,并行任务和相关的并发设计。
是一种构架用于锁定和等待不同于内置同步和监测器的条件。
随时准备使用的类用于在单个变量上的锁定自由,线程安全的编程。
开发一个Concurrent Java Application
本节是演示如何使用Java concurrency utility API来开发一个多线程的在线订单程序的电子商务应用程序。在应用程序生效并授权命令之后,把它们放在订单处理列队(java.util.concurrent.BlockingQueue)。订单处理器线程池不断的对订单进行测验,而且当这些订单可以使用时进行处理。
解耦应用程序的订单处理代码提供了增加和减少订单处理率的灵活性,通过改变线程池的大小。在一个并发BlockingQueue中放入订单对象确保一个处理器处理一个订单,而且它要照顾自动同步。
在以下小节中的代码段是截取于伴随本文中的应用程序源代码。