代码之家  ›  专栏  ›  技术社区  ›  Laurent K

线程同步问题(在Java中)

  •  4
  • Laurent K  · 技术社区  · 16 年前

    我的Java应用程序有一个加载任务,它需要两个服务器调用,可以并行化。所以我启动了一个线程T1(做 任务1 )和螺纹t2(用于 任务2 ) 然后我想做一个具体的任务, 任务3 当其他两项任务(1&2)都结束时。当然,我不知道 任务1 任务2 将先完成…

    哪种方法对您来说是最简单(也是最安全)的编码方式?

    谢谢你的帮助

    4 回复  |  直到 11 年前
        1
  •  7
  •   Ran Biron    16 年前

    你有几个选择:

    1. 如果task3在一个单独的线程上,而task1和task2线程对其任务是独占的(没有线程池),并且在任务完成时完成,则可以使用t1.join();t2.join();等待两个线程。优点:容易。缺点:情况很少这么简单。
    2. 如果task3在一个单独的线程上,则可以在所有线程之间使用java.util.concurrent.countdownloatch共享。任务3将等待闩锁,而任务1和任务2将减小闩锁。优点:很容易,对环境一无所知。缺点:需要在真正需要之前创建T3。
    3. 如果只有在task1和task2完成后才能创建task3(在task1和task2完成之前没有单独的线程),则必须构建更复杂的线程。我建议您创建自己的ExecutorService,它接受一个附加于未来的条件,并且只在条件改变时执行未来,或者创建一个管理服务,根据这些条件检查条件并提交给定的未来。记住,这是我的头,可能有更简单的解决方案。优点:资源友好。缺点:复杂。
        2
  •  2
  •   David Webb    16 年前

    你可以 join 二者都 t1 t2 (按任意顺序),然后在加入后运行task3。

        3
  •  0
  •   gizmo    16 年前

    在任务3中实现侦听器接口,并将其注册到任务1和任务2。任务1和任务2必须在结束前调用其侦听器。这样,您可以在任务3中记录哪些任务已经完成,当两个任务都完成时,您可以执行第三个任务。

    当然,如果在任务1/2的上可以退出异常,请不要忘记将task3作为其未捕获的异常处理程序。

        4
  •  0
  •   mitchnull    16 年前

    如果您不想在两个工作线程(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...
    }