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

时间:2013-04-11 18:33:32

标签: java multithreading

在这段代码中,两者加入和断开是什么意思? 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();
   }
}

10 个答案:

答案 0 :(得分:281)

引用Thread.join() method javadocs

  

join()等待此线程死亡。

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

  1. 主线程创建并启动t1t2个线程。两个线程并行开始运行。
  2. 主线程调用t1.join()等待t1线程完成。
  3. t1线程完成,t1.join()方法在主线程中返回。请注意,t1可能已在join()来电之前完成,在这种情况下join()来电将立即返回。
  4. 主线程调用t2.join()等待t2线程完成。
  5. t2线程完成(或者它可能在t1线程之前完成)并且t2.join()方法在主线程中返回。
  6. 重要的是要了解t1t2线程一直在运行 ,但启动它们的主线程需要等待它们在它之前完成可以继续这是一种常见的模式。此外,t1和/或t2可能在主线程调用join()之前完成。如果是这样,那么join()将不会等待,但会立即返回。

      

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

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

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

    while (true) {
    

    while循环中使用连接是一种奇怪的模式。通常,您将执行第一个连接,然后在每种情况下适当地处理InterruptedException的第二个连接。无需将它们放在循环中。

答案 1 :(得分:64)

这是最喜欢的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本身可以并行运行,而不管t1和{{上的加入调用序列 1}}。 t2主题必须等待

答案 2 :(得分:43)

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

答案 3 :(得分:17)

一张图片胜过千言万语。

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

希望有用,有关详细信息,请点击here

答案 4 :(得分:8)

当线程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内存模型不需要转移' “共享”的新价值'从threadB到主线程没有heppens-before关系(线程开始,线程连接,'同步'关键字的使用,AtomicXXX变量的使用等)。

答案 5 :(得分:2)

来自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实现相同的功能。一些例子是

  1. ExecutorService
  2. 上使用invokeAll
  3. 使用CountDownLatch
  4. 使用Executors或{{1}} {{1}}(自java 8开始)
  5. 参考相关的SE问题:

    ForkJoinPool

答案 6 :(得分:2)

简单地说:
t1.join()完成t1后返回。
除了等待它完成之外,它对t1进行线程无效。
当然,代码如下 t1.join()只会在执行之后执行 t1.join()返回。

答案 7 :(得分:0)

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

  

在下面,它是纯的wait()和notify()机制。

我们都知道,当我们在任何对象(t1)上调用wait()时,调用对象(主)都会发送到等候室(处于阻塞状态)。

在这里,主线程正在调用join(),它是幕后的wait()。因此主线程将等待,直到通知它。 在t1结束运行(线程完成)时发出通知。

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

答案 8 :(得分:0)

希望有帮助!

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
}

答案 9 :(得分:-3)

让我们说主线程启动线程t1和t2。现在,当调用t1.join()时,主线程会自行挂起,直到线程t1死掉,然后自行恢复。 类似地,当t2.join()执行时,主线程再次挂起,直到线程t2死亡然后恢复。

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

此外,这里并不真正需要while循环。