线程同步问题(在java中)

时间:2008-10-08 07:33:36

标签: java multithreading concurrency synchronization

我的java应用程序有一个加载任务,需要两个可并行化的服务器调用。所以我启动了一个Thread t1(执行 task1 )和一个Thread t2(用于 task2 )。 我希望在其他任务(1& 2)结束时执行特定任务 task3 。当然我不知道 task1 task2 中哪一个会先完成......

哪种方法最简单(也是最安全)的方法来编写代码?

感谢您的帮助

4 个答案:

答案 0 :(得分:7)

你有几个选择:

  1. 如果task3在一个单独的线程上并且task1和task2线程对其任务是独占的(没有线程池)并在任务完成时完成,则可以使用{T1.join(); T2.join();}等待两个线程。优点:简单。缺点:情况很少那么简单。
  2. 如果task3在一个单独的线程上,您可以使用在所有线程之间共享的java.util.concurrent.CountDownLatch。任务3将等待锁存器,而task1和task2将减少它。优点:相当容易,不注意环境。缺点:要求T3在真正需要之前创建。
  3. 如果task3只应在task1和task2完成之后创建(在task1和task2完成之后没有单独的线程),你必须构建一些更复杂的东西。我建议您创建自己的ExecutorService,该条件是未来的条件,只在条件发生变化时执行未来,或者创建一个管理服务来检查条件并根据这些条件提交给定的期货。记住,这是我的头脑,可能有更简单的解决方案。优点:资源友好。缺点:复杂。

答案 1 :(得分:2)

您可以join t1t2(按任意顺序),然​​后在加入后运行task3。

答案 2 :(得分:0)

在task3中实现一个监听器接口,并将其注册到task1& TASK2。 Task1和Task2必须在结束之前调用他们的监听器。这样,您可以在task3中记录哪个任务已经完成,当两个任务完成后,您可以执行第三个任务。

当然,如果你的task1 / 2可以退出异常,不要忘记将task3作为其UncaughtExceptionHandler

答案 3 :(得分:0)

我不想在完成工作时终止2个工作线程(task1和task2),然后你可以在task3中等待一个条件,直到其他两个完成。像这样:

public class Master {

    private Object monitor_ = new Object();
    private boolean task1Finished_;
    private boolean task2Finished_;

    class Task1 extends Thread {

        public void run() {
            // do stuff
            synchronized (monitor_) {
                task1Finished_ = true;
                monitor_.notifyAll();
            }
            // keep on working
        }
    }

    class Task2 extends Thread {

        public void run() {
            // do stuff
            synchronized (monitor_) {
                task1Finished_ = true;
                monitor_.notifyAll();
            }
            // keep on working
        }
    }

    class Task3 extends Thread {

        public void run() {
            synchronized (monitor_) {
                while (!task1Finished_ || !task2Finished_) {
                    try {
                        monitor_.wait();
                    }
                    catch (InterruptedException ignored) {
                    }
                }
            }
            // do stuff
        }
    }
    // start tasks1, task2 and task3...
}