简体   繁体   English

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

[英]Java: calling join() multiple times on same thread?

I have threads A, B and C. I'm starting A and B simultaneously and thread C will execute it's logic after A and B end. 我有线程A,B和C.我同时启动A和B,线程C将在A和B结束后执行它的逻辑。 I also want to do other operations after A ends and different operations after thread B ends. 我也想在A结束后进行其他操作,并在线程B结束后进行不同的操作。

So I designed it this way: 所以我这样设计:

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
    }
};

I'm worried that I'm doing something wrong here, as I couldn't find any tips about calling join() multiple times on same thread. 我担心我在这里做错了,因为我找不到任何关于在同一个线程上多次调用join()的提示。

On the other hand, I have no idea how can I achieve what I wand in other way. 另一方面,我不知道如何以其他方式实现我的魔杖。 I could probably just use 我可能只是用

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

but for me it looks worse. 但对我来说,它看起来更糟糕。

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

If you asking why at all do such things... 如果你问为什么要做这样的事情......

There are two buttons b1 and b2. 有两个按钮b1和b2。

x.performAction() shows indicator on b1 while in the background I'm loading data from DB (it's done in Thread a). x.performAction()显示b1上的指示符,而在后台我正在从DB加载数据(它在线程a中完成)。 y.performAction() makes similar thing for b2 but loads different portion of data (Thread b). y.performAction()为b2做了类似的事情但加载了不同的数据部分(线程b)。

Putting start() and join() in actionPerformed() causes showing indicator as long as data is loading. 只要数据正在加载,将start()和join()放在actionPerformed()中会导致显示指示符。 When data loading is finished, indicator disappears. 数据加载完成后,指示消失。

There is also other action. 还有其他行动。 Before data loading is finished, button is disabled (user can't click it). 在数据加载完成之前,按钮被禁用(用户无法单击它)。

The point is to enable both buttons (letting the user to click them) only after both portions of data is loaded from DB. 关键是只有在从DB加载两部分数据后才能启用这两个按钮(让用户单击它们)。 The point is also to allow showing indicators separately - if Thread a finishes before Thread b, there is no point for showing indicator on button b1. 这一点也是为了允许单独显示指标 - 如果线程a在线程b之前完成,则在按钮b1上没有显示指示符的点。

Consider what can happen with this code: 考虑一下这段代码会发生什么:

a.join();
b.join();
proceed();
  1. Both threads may be dead—proceed immediately; 两个线程可能会立即死亡;
  2. a dead, b alive: block on second line until b dead; a死, b活:在第二行,直到块b死;
  3. a alive, b dead: block on first line until a dead; a活的, b死:上第一行,直到块a死;
  4. both alive: block on first line until a dead, then block as needed until b dead. 两个活:在第一行块直到a死,然后根据需要,直到方框b死亡。

All four cases share the following invariant: 所有四种情况共享以下不变量:

proceed() is reached as soon as , but no sooner than , both a and b are dead. proceed()尽快达成,但不早于 ,无论是ab都死了。

See the JavaDoc on join() 请参阅join()上的JavaDoc

... uses a loop of this.wait calls conditioned on this.isAlive . ...使用this.wait调用this.isAlive

so it is safe to call join as many times as you like - a dead thread will always have false for isAlive . 所以你可以多次调用join 安全的 - 对于isAlive死线程总是会有false

It is also not possible to resurrect a thread. 它也没有能够复活一个线程。

It is never legal to start a thread more than once. 不止一次启动线程永远不合法。 In particular, a thread may not be restarted once it has completed execution. 特别是,一旦完成执行,线程可能无法重新启动。

It is safe to join multiple times on a thread 在线程上多次连接是安全的

Also i noticed something not quite right if you want this code to do nothing while BOTH threads are alive why not just 此外,我注意到一些不太正确的事情,如果你希望这个代码什么都不做,而两个线程还活着,为什么不呢

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

That just makes more sense to me than creating a loop to do nothing 这对我来说比创建一个无所事事的循环更有意义

EDIT: add a break so the loop with stop after executing once 编辑:添加一个休息,以便循环执行一次后停止

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM