【问题标题】:Running a task in parallel to another task与另一个任务并行运行一个任务
【发布时间】:2012-06-28 10:38:00
【问题描述】:

我有以下使用FooProcessor 类的Foo 类。所以我想做的是,在运行 cp1 实例进程方法时,我想并行运行cp2.process()

public class Foo {

    public static void main(String [] args){

        FooProcessor cp1 = new FooProcessor();
        FooProcessor cp2 = new FooProcessor();

        cp1.process();
        // in parallel process cp2.process();
    }

}

public class FooProcessor {
    public void process(){
        System.out.println("Processing..");
    }
}

但是,我希望 cp1 按顺序运行,所以我希望它运行并完成,如果 cp2 没有完成或失败,那很好。如果它没有失败,我想加入结果。它没有返回此示例中的任何内容,但我想返回结果。

为此,应该使用TaskExecutor吗?还是线程?

我只希望 cp2 与 cp1 并行运行。或者如果我添加更多让我们说 cp3,我希望它也与 cp1 并行运行。

【问题讨论】:

  • “我想要 cp1 顺序” - 你的意思是你想让 cp1 和 cp2 并行运行,但是一旦 cp1 完成它正在做的事情就停止两者,然后要么从 cp2 获取结果,如果它有也完成了,否则停止?

标签: java multithreading threadpool executor


【解决方案1】:

如果您正在编写自己的独立应用程序,使用线程可能是最简单的方法。如果您在 Java EE 环境中,则不应创建自己的 Thread 对象,而应使用其他一些机制(例如发送消息并让消息侦听器处理您发送的信号)。这是为了让 Java EE 容器控制线程池等资源的使用。

使用线程的示例:

Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
         executeSomeCodeInP1();
    }
});

Thread t2 = new Thread(new Runnable() {
    @Override
    public void run() {
         executeSomeCodeInP2();
    }
});

t1.start();
t2.start();

// if you want to wait for both threads to finish before moving on, 
// "join" the current thread
t1.join();
t2.join();

【讨论】:

  • 这不是我真正想要的
【解决方案2】:

总结一下我的实现方式:

  • 通过ExecutorService 运行您的不同进程,例如ExecutorService executor = Executors.newFixedThreadPool(nThreads);
  • 将所有任务的Futures 存储在一个列表中(由 ExecutorService#submit 返回)
  • 等待future1.get() 完成,其中future1 是链接到cp1 的未来
  • 一旦get 返回(cp1 已完成)cancel 所有其他期货,(或shutdownNow 执行程序服务,如果您不再需要执行程序)
  • 要使取消过程正常工作,您的 cp2、cp3 等需要实施中断政策,使他们尽快停止正在做的事情。

【讨论】:

    【解决方案3】:

    您当然可以使用简单明了的线程
    如果您知道需要向处理器类添加更多方法,并为它的给定实例保持执行顺序 - 假设您首先运行方法 foo,然后运行方法 bar,并且您希望它们异步运行,但保持执行顺序(首先是 foo,然后是 bar),我会考虑使用 Active Object 模式。
    我也推荐使用这种方法,因为对于处理器类的用户来说,它会隐藏实现细节。
    此外,考虑提供一个decorator/wrapper,它将为您的对象提供这种异步能力 - 这样您就可以控制哪个对象异步运行,哪个不是,并且您不必“污染”您的具有异步调用所需代码的处理器类。
    在这种情况下的使用示例将是 -

    AsyncProcessor ap  = new AsyncProcessor(p1);
    ap.process();  //executed asynchronously
    Proccessor p2 = new Processor();
    p2.process(); //executed synchronously
    



    另一个方法是使用您提到的执行者 - 这可以通过实现一个线程池并将“执行单元推送给它”来实现。
    一个执行单元将包含目标对象(cp1、cp2、...)和要执行的方法(当前 - 仅进程)
    线程将从队列中获取“一个执行单元”并运行它们。
    实现类似于活动对象,但用户的“接口”不同,因为它使用“TaskExecutor”类为其提供“执行单元”

    【讨论】:

    • java中jdk中有AsyncProcessor吗?
    【解决方案4】:

    根据https://stackoverflow.com/a/2269177/454167

    您可以使用类似AsyncTaskExecutor[1] 的东西,它返回一个Future 对象。然后你可以等待 Future 知道 cp2 是否返回成功。

    [1]http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/core/task/AsyncTaskExecutor.html#submit%28java.lang.Runnable%29

    【讨论】:

    • 我没有使用弹簧。我不能。
    【解决方案5】:

    线程将是一个不错的选择...类似于接受新线程并启动它们的方法...

    【讨论】:

      猜你喜欢
      • 2014-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-31
      • 2022-07-11
      • 1970-01-01
      • 2023-02-26
      • 1970-01-01
      相关资源
      最近更新 更多