技术开发 频道

Active Object并发模式在Java 中的应用

  Java 对 Active Object 支持

  Java JDK 1.3 引入了 java.util.Timer 和 java.util.TimerTask,提供了对 timer-based 并发任务支持,Timer 和 TimerTask 可以看作是 Active Object 设计模式在 Java 中的实现。不过,在这里我们不打算过多讨论 Timer 及其 TimerTask。由于 Timer 和 TimerTask 的缺陷性,例如 Timer 使用单线程执行 TimerTask 导致的 Task 调度时间的不精确性等问题。从 Java1.5 开始,Java 建议使用 ScheduledThreadPoolExecutor 作为 Timer 的替代。

  在这里,我们讨论一下自 Java1.5 引入的 Executor Framework。Java1.5 的 Executor Framework 可以看作是 Active Object 设计模式在 Java 中的体现。不过 Java 的 Executor Framework 极大地简化了我们前面所讨论的 Active Object 所定义的模式。

  Java 的 Executor Framework 是一套灵活强大的异步任务执行框架,它提供了标准的方式解耦合任务的提交与任务的执行。Java Executor 框架中的任务指的是实现了 Runnable 或者 Callable 接口的对象。Executor 的示例用法如清单 8 所示:

  清单 8. Java Executor 示例代码

public class TaskExecutionTcpServer {
    
private static final int NTHREADS = 100;
    
private static final Executor exec = Executors.newFixedThreadPool(NTHREADS);

    
public static void main(String[] args) throws IOException {
        ServerSocket socket
= new ServerSocket(80);
        
while (true) {
            final Socket connection
= socket.accept();
            Runnable task
= new Runnable() {
                
public void run() {
                    handleRequest(connection);
                }
                
public void handleRequest(Socket connection) {
                    
// Handle the incoming socket connection from                        
                    
//individual client.
                }
            };
            exec.execute(task);
        }
    }
}

  在示例 8 中,我们创建了一个基于线程池的 Java Executor, 每当新的 TCP 连接进来的时候,我们就分配一个独立的实现了 Runnable 任务来处理该连接,所有这些任务运行在我们创建的有 100 个线程的线程池上。

  我们可以从 Active Object 设计模式的角度来审视一下 Java Executor 框架。Java Executor 框架以任务 (Task) 为中心,简化了 Active Object 中的角色分工。可以看到,实现 Runnable 或者 Callable 接口的 Java Executor 任务整合了 Method Request 和 Servant 的角色 , 通过实现 run() 或者 call() 方法实现应用逻辑。Java Executor 框架并没有显式地定义 Proxy 接口,而是直接调用 Executor 提交任务,这里的 Executor 相当于 Active Object 中调度者角色。从调用者的角度来看,这看起来并不像是在调用一个普通对象方法,而是向 Executor 提交了一个任务。所以,在这个层面上说,并发的底层细节已经暴露给了调用者。对于 Java 的开发者来说,如果你不担心这样的底层并发细节直接暴露给调用者,或者说你的应用并不需要像对待普通对象一样对待并发对象,Java 的 Executor 框架是一个很好的选择。相反,如果你希望隐藏这样的并发细节,希望像操纵普通对象一样操纵并发对象,那你就需要如本文上节所描述的那样,遵循 Active Object 设计原则 , 清晰地定义各个角色,实现自己的 Active Object 模式。

  总而言之,Java Executor 框架简化了 Active Object 所定义的模式,模糊了 Active Object 中角色的分工,其基于生产者 / 消费者模式,生产者和消费者基于任务相互协作。

0
相关文章