这个线程连接代码是啥意思?

Posted

技术标签:

【中文标题】这个线程连接代码是啥意思?【英文标题】:What does this thread join code mean?这个线程连接代码是什么意思? 【发布时间】:2013-04-04 02:06:26 【问题描述】:

在这段代码中,两个join和break是什么意思? t1.join() 导致 t2 停止直到 t1 终止?

Thread t1 = new Thread(new EventThread("e1"));
t1.start();
Thread t2 = new Thread(new EventThread("e2"));
t2.start();
while (true) 
   try 
      t1.join();
      t2.join();
      break;
    catch (InterruptedException e) 
      e.printStackTrace();
   

【问题讨论】:

docs.oracle.com/javase/tutorial/essential/concurrency/join.html 和 docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html 既然会阻塞等待线程终止,那为什么要用while循环呢? @MahdiElMasaoudi 我想,即使线程被中断也要继续等待?可能不是这样做的好方法 如果有帮助记得在这里接受答案。 如前所述,您不需要while(true) 来调用join 方法。 【参考方案1】:

这个线程加入代码是什么意思?

引用Thread.join() method javadocs:

join() 等待该线程终止。

有一个线程正在运行您的示例代码,它可能是main thread。

    主线程创建并启动t1t2 线程。两个线程开始并行运行。 主线程调用t1.join() 等待t1 线程完成。 t1 线程完成,t1.join() 方法在主线程中返回。请注意,t1 可能在调用 join() 之前已经完成,在这种情况下,join() 调用将立即返回。 主线程调用t2.join()等待t2线程完成。 t2 线程完成(或者它可能在 t1 线程完成之前完成)并且 t2.join() 方法在主线程中返回。

了解t1t2 线程一直在并行运行很重要,但是启动它们的主线程需要等待它们完成才能继续。这是一种常见的模式。此外,t1 和/或t2 可能在主线程调用join() 之前完成。如果是这样,那么join() 不会等待,而是会立即返回。

t1.join() 表示导致 t2 停止直到 t1 终止?

没有。正在调用t1.join()main 线程将停止运行并等待t1 线程完成。 t2 线程并行运行,完全不受t1t1.join() 调用的影响。

就 try/catch 而言,join() throws InterruptedException 意味着调用 join() 的主线程本身可能被另一个线程中断。

while (true) 

while 循环中加入连接是一种奇怪的模式。通常,您会先进行第一次连接,然后再进行第二次连接,以在每种情况下适当地处理 InterruptedException。无需将它们置于循环中。

【讨论】:

+1 这是一个非常奇怪的模式,可能可以删除。 如果 t1 先完成,然后 t2 完成。这似乎是一个连续的过程。一个线程首先完成,然后另一个。多线程有什么意义? 因为t1t2 可以并行运行。只是main 需要它们都完成才能继续。这是@user697911 的典型模式。 while 循环存在是因为(我猜)它想在join() 调用被中断时重试?我当然不会那样写@user697911。 循环用于确保t1t2 都完成。 IE。如果t1 抛出InterruptedException,它将循环返回并等待t2。另一种方法是在各自的 Try-Catch 中等待两个线程,这样可以避免循环。此外,根据EventThread,这样做是有意义的,因为我们正在运行 2 个线程,而不是一个。【参考方案2】:

这是一个最喜欢的 Java 面试问题。

Thread t1 = new Thread(new EventThread("e1"));
t1.start();
Thread e2 = new Thread(new EventThread("e2"));
t2.start();

while (true) 
    try 
        t1.join(); // 1
        t2.join(); // 2  These lines (1,2) are in in public static void main
        break;
    

t1.join() 的意思是,t1 说类似“我想先完成”。 t2 也是如此。无论是谁启动了t1t2 线程(在本例中为main 方法),main 都会等到t1t2 完成他们的任务。

但是,需要注意的重要一点是,t1t2 本身可以并行运行,而与 t1t2 上的加入调用顺序无关。必须等待的是main/daemon线程。

【讨论】:

很好的例子。关于“可以并行运行”:那又怎样?重要的是主线程将首先等待 t1,然后等待 t2。 t1 或 t2 在做什么真的没关系(从主线程的角度来看) 你提到了“主/守护进程”线程。我理解的主要内容,但守护进程与它无关。主线程是非守护线程。 t1.join(); t2.join(); 将不允许执行连接的线程继续,直到两个线程都终止。在其他地方没有非常不寻常的代码的情况下,连接的顺序无关紧要。 那么 t2.join() 只有在 t1 完成后才会被调用吗? 换句话说,如果我们想“序列化” t1 和 t2 线程的执行,我们需要将 t1.join() 放在 t1.start() 之后,因为主线程启动了 t1(和 t2之后),当然也可以从 try/catch 中删除它。显然,这样做的后果将是失去并行性。【参考方案3】:

join() 表示等待线程完成。这是一种拦截方法。您的主线程(执行join() 的线程)将在t1.join() 行上等待,直到t1 完成其工作,然后将对t2.join() 执行相同的操作。

【讨论】:

【参考方案4】:

一张图片胜过一千个字。

    Main thread-->----->--->-->--block##########continue--->---->
                 \                 |               |
sub thread start()\                | join()        |
                   \               |               |
                    ---sub thread----->--->--->--finish    

希望有用,更多详情点击here

【讨论】:

清晰准确。 调用join()的线程是处于BLOCKED状态还是WAITING状态? 当一个线程被阻塞等待一个监视器时,它的状态是BLOCKED。当一个线程正在等待另一个线程时,它的状态是WAITING。更多详情请点击我的其他博客。 java thread state 没有回答问题。【参考方案5】:

当线程 tA 调用 tB.join() 时,其原因不仅是等待 tB 死亡或 tA 自身被中断,而且会在 tB 中的最后一条语句和 tA 线程中 tB.join() 之后的下一条语句之间创建发生前的关系。

All actions in a thread happen-before any other thread successfully returns from a join() on that thread.

意思是程序

class App 
    // shared, not synchronized variable = bad practice
    static int sharedVar = 0;
    public static void main(String[] args) throws Exception 
        Thread threadB = new Thread(() -> sharedVar = 1;);
        threadB.start();
        threadB.join();

        while (true) 
            System.out.print(sharedVar);
    

总是打印

>> 1111111111111111111111111 ...

但是程序

class App 
    // shared, not synchronized variable = bad practice
    static int sharedVar = 0;
    public static void main(String[] args) throws Exception 
        Thread threadB = new Thread(() -> sharedVar = 1;);
        threadB.start();
        // threadB.join();  COMMENT JOIN

        while (true)
            System.out.print(sharedVar);
    

不仅可以打印

>> 0000000000 ... 000000111111111111111111111111 ...

但是

>> 00000000000000000000000000000000000000000000 ... 

始终只有“0”。

因为 Java 内存模型不需要在没有 heppens-before 关系的情况下将“sharedVar”的新值从 threadB“传输”到主线程(线程启动、线程连接、“synchonized”关键字的使用、AtomicXXX 变量的使用等)。

【讨论】:

【参考方案6】:

简单地说:t1.join()t1 完成后返回。它不会对线程t1 做任何事情,除了等待它完成。 自然,代码如下 t1.join() 只会在之后执行 t1.join() 返回。

【讨论】:

只有在t1.join()返回+1后才会执行【参考方案7】:

来自 oracle 文档page on Joins

join 方法允许一个线程等待另一个线程完成。

如果 t1 是一个线程当前正在执行的Thread 对象,

t1.join() : causes the current thread to pause execution until t1's thread terminates.

如果 t2 是一个线程当前正在执行的Thread 对象,

t2.join(); causes the current thread to pause execution until t2's thread terminates.

join API 是低级 API,在早期的 java 版本中已经引入。在一段时间内(尤其是 jdk 1.5 版本),在并发方面发生了很多变化。

您可以使用 java.util.concurrent API 实现相同的目的。一些例子是

    ExecutorService 上使用invokeAll 使用CountDownLatch 使用Executors 的ForkJoinPool 或newWorkStealingPool(从java 8 开始)

参考相关的 SE 问题:

wait until all threads finish their work in java

【讨论】:

【参考方案8】:

对我来说,Join() 行为总是令人困惑,因为我试图记住谁会等待谁。 不要试图那样记住它。

下面是纯wait()和notify()机制。

我们都知道,当我们在任何 object(t1) 上调用 wait() 时,调用 object(main) 会被发送到等候室(阻塞状态)。

这里,主线程正在调用 join(),它实际上是 wait()。所以主线程会一直等到收到通知。 t1 完成运行(线程完成)时会发出通知。

收到通知后,main 走出等候室,继续执行。

【讨论】:

嗯,这是否意味着我可以将其视为 javascriptawait 函数?哈哈【参考方案9】:

希望对您有所帮助!

package join;

public class ThreadJoinApp 

    Thread th = new Thread("Thread 1") 
        public void run() 
            System.out.println("Current thread execution - " + Thread.currentThread().getName());
            for (int i = 0; i < 10; i++) 
                System.out.println("Current thread execution - " + Thread.currentThread().getName() + " at index - " + i);
            
        
    ;

    Thread th2 = new Thread("Thread 2") 
        public void run() 
            System.out.println("Current thread execution - " + Thread.currentThread().getName());

            //Thread 2 waits until the thread 1 successfully completes.
            try 
            th.join();
             catch( InterruptedException ex) 
                System.out.println("Exception has been caught");
            

            for (int i = 0; i < 10; i++) 
                System.out.println("Current thread execution - " + Thread.currentThread().getName() + " at index - " + i);
            
        
    ;

    public static void main(String[] args) 
        ThreadJoinApp threadJoinApp = new ThreadJoinApp();
        threadJoinApp.th.start();
        threadJoinApp.th2.start();
    

    //Happy coding -- Parthasarathy S

【讨论】:

【参考方案10】:

假设我们的主线程启动线程 t1 和 t2。现在,当调用 t1.join() 时,主线程会挂起自己,直到线程 t1 死亡然后自己恢复。 同样,当 t2.join() 执行时,主线程再次挂起,直到线程 t2 死亡然后恢复。

所以,这就是它的工作原理。

另外,这里也不需要 while 循环。

【讨论】:

以上是关于这个线程连接代码是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

Java JVM 分析,线程状态 - “监视器”状态是啥意思?

Python多线程是啥意思?

mysql的sleep线程是啥意思

线程安全是啥意思

网页提示错误代码405。是啥意思?如何解决?求高人指点。。

CoreData 是啥意思不是线程安全的?