Java:在同一个线程上多次调用join()?

时间:2014-09-16 10:47:36

标签: java multithreading

我有线程A,B和C.我同时启动A和B,线程C将在A和B结束后执行它的逻辑。我也想在A结束后进行其他操作,并在线程B结束后进行不同的操作。

所以我这样设计了它:

final Thread a = new Thread() {
    @Override
    public void run() {
        // do something
    }
};

final Thread b = new Thread() {
    @Override
    public void run() {
        // do something
    }
};

AbstractAction x = new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        a.start();
        try {
            a.join();
        } catch (InterruptedException e1) {
        }

        // do some other things
    }
};

AbstractAction y = new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        b.start();
        try {
            b.join();
        } catch (InterruptedException e1) {
        }

        // do some more different things
    }
};

Thread c = new Thread() {
    @Override
    public void run() {
        try {
            a.join();
            b.join();
        } catch (InterruptedException e) {
        }

        // do things after a and b ends
    }
};

我担心我在这里做错了,因为我找不到任何关于在同一个线程上多次调用join()的提示。

另一方面,我不知道如何以其他方式实现我的魔杖。我可能只是使用

while (a.isAlive() || b.isAlive()) {
    // do nothing
}
// do things after a and b ends

但对我而言看起来更糟。

-----更新1 -----

如果你问为什么要这样做......

b1和b2有两个按钮。

x.performAction()在b1中显示指示符,而在后台我正在从DB加载数据(它在线程a中完成)。 y.performAction()为b2做了类似的事情但加载了不同的数据部分(线程b)。

在actionPerformed()中放置start()和join()会导致显示指标,只要数据正在加载即可。数据加载完成后,指示消失。

还有其他行动。在数据加载完成之前,按钮被禁用(用户无法单击它)。

关键是只有在从DB加载两部分数据后才能启用这两个按钮(让用户单击它们)。这一点也是为了允许单独显示指标 - 如果线程a在线程b之前完成,则按钮b1上没有显示指示符的点。

3 个答案:

答案 0 :(得分:2)

考虑一下这段代码会发生什么:

a.join();
b.join();
proceed();
  1. 两个线程可能会立即死亡;
  2. a死了,b还活着:在第二行阻止,直到b死亡;
  3. a还活着,b死了:在第一行阻止,直到a死亡;
  4. 两者都存活:阻塞第一行直到a死亡,然后根据需要阻止直到b死亡。
  5. 所有四种情况共享以下不变量:

    proceed()一旦到达,但不早于ab都已死亡。

答案 1 :(得分:1)

请参阅join()

上的JavaDoc
  

...使用以this.wait为条件的this.isAlive来电循环。

所以 可以安全地随心所欲地调用join - 对于false,死线程总是isAlive

恢复线程也是not

  

不止一次启动线程永远不合法。特别是,一旦完成执行,线程可能无法重新启动。

答案 2 :(得分:0)

在线程上连接多次是安全的

此外,如果您希望此代码在BOTH线程处于活动状态时无效,那么我注意到了一些不太正确的事情

while (!a.isAlive() && !b.isAlive()) {
    // do things
    break;
}

这对我来说比创建一个不做任何事情的循环更有意义

编辑:添加一个中断,以便在执行一次后停止循环