工作流设计模式与任务模式相结合?

时间:2017-01-26 18:28:36

标签: java design-patterns

我目前正在开展一项执行长期非线性任务的企业应用程序。

工作流程的抽象:

  1. 收集必要的信息(可能需要几分钟,但并非总是必要)
  2. 处理数据(总是需要很长时间)
  3. 通知几位对结果进行后期处理的工作人员(在新任务中)
  4. 现在,我已经创建了2个服务,可以解决第1步和第2步。 由于服务不应该彼此了解,我希望有一个更高阶的组件来协调任务的3个步骤。可以把它想象成一个Callable,它将任务发送到服务一个,当服务1返回结果时再次唤醒,将其发送到服务2,......,将最终结果发送给所有后处理器并结束任务。 但由于它可能有100到3900个排队任务,我不想用任务控制callables启动100&000; 000s线程,即使在99.9%的时间内仍处于空闲状态巨大的开销。

    所以让任何人想到控制这个封装在任务对象中的生产者消费者队列式模式,或者有人知道一个简化我关注的框架吗?

1 个答案:

答案 0 :(得分:1)

除了actor框架之外,我还建议使用两种主要的方法来处理普通的旧Java:

  • 使用我们提交任务的ExecutorService。可以使用Future对象同步正确的步骤顺序。可以使用下面显示的Phaser a来同步整套任务。

  • 使用Fork/Join framework

以下是使用简单执行程序服务的示例。 Workflow类具有执行程序和移相器(同步屏障)。每次执行工作流程时,它都为每个步骤(即数据收集,处理和后处理)提交新任务。每个任务都使用这些相位器来指示它何时开始和停止。

public class Workflow {

    private final ExecutorService executor;
    private final Phaser phaser;

    public Workflow(ExecutorService executor, Phaser phaser) {
        this.executor = executor;
        this.phaser = phaser;
    }

    public void execute(int request) throws InterruptedException, ExecutionException {
        executor.submit(() -> {
            phaser.register();
            // Data collection
            Future<Integer> input = executor.submit(() -> {
                phaser.register();
                System.out.println("Gathering data for call " + request);
                phaser.arrive();
                return request;
            });
            // Data Processing
            Future<Integer> result = executor.submit(() -> {
                phaser.register();
                System.out.println("Processing call " + request);
                Thread.sleep(5000);
                phaser.arrive();
                return request;
            });
            // Post processing
            Future<Integer> ack = executor.submit(() -> {
                phaser.register();
                System.out.println("Notyfing processors for call " + request);
                phaser.arrive();
                return request;
            });
            final Integer output = ack.get();
            phaser.arrive();
            return output;
        });
    }

}

在关闭执行程序之前,调用者对象使用phaser对象知道所有子任务(步骤)何时完成。

public static void main(String[] args) throws InterruptedException, ExecutionException {
    final Phaser phaser = new Phaser();
    final ExecutorService executor = Executors.newCachedThreadPool();
    Workflow workflow = new Workflow(executor, phaser);

    phaser.register();
    for (int request=0 ; request<10 ; request++) {
        workflow.execute(request);
    }

    phaser.arriveAndAwaitAdvance();
    executor.shutdown();
    executor.awaitTermination(30, TimeUnit.SECONDS);    
}