如果join阻塞了主线程,为什么它不循环阻塞?

时间:2019-06-28 06:48:29

标签: java multithreading java-threads

可以使用Thread实例的join()方法将线程执行的开始“联接”到另一个线程执行的结束,以便在另一个线程结束之前线程不会开始运行。如果在Thread实例上调用join(),则当前正在运行的线程将阻塞,直到Thread实例执行完毕

但是如果我有多个线程,并且在循环内调用join时。所有线程并行运行。但是根据连接概念,首先连接的线程应该完成,然后只有主线程才允许连接其他线程。

public class MultiThreading implements Runnable {


private int name;
public MultiThreading(int number) {
    name =number;
}

@Override
public void run() {
    for (int i = 0; i <= 10; i++ ) {

           System.out.println("Thread number :" + name +" Printed value "+i);

        try {
            Thread.sleep(100);
        } catch (final InterruptedException e) {
            return;
        }
    }
}


public static void main(String[] args) throws InterruptedException {

    final Thread[] workers = new Thread[3];
    for (int i = 0; i < nthreads; ++i) {
        workers[i] = new Thread(new MultiThreading(i));
    }
    for (final Thread t : workers) {
        t.start();

    }

    for (final Thread t : workers) {
        t.join();
        System.out.println("Thread joind to main thread : " + t.getName());
    }
    System.out.println("Main thread ends");
}

}

在上面的代码中,如果连接了第一个线程,则应阻塞主线程,并且不应让其他线程加入(直到连接的线程完成run方法的执行)。但是所有线程都是并行连接的。输出就像-

Thread number :0 Printed value 0
Thread number :1 Printed value 0
Thread number :2 Printed value 0
Thread number :0 Printed value 1
Thread number :1 Printed value 1
Thread number :2 Printed value 1
Thread number :0 Printed value 2
Thread number :1 Printed value 2
Thread number :2 Printed value 2
Thread number :0 Printed value 3
Thread number :1 Printed value 3
Thread number :2 Printed value 3
Thread number :0 Printed value 4
Thread number :1 Printed value 4
Thread number :2 Printed value 4
Thread number :1 Printed value 5
Thread number :0 Printed value 5
Thread number :2 Printed value 5
Thread number :0 Printed value 6
Thread number :1 Printed value 6
Thread number :2 Printed value 6
Thread number :1 Printed value 7
Thread number :0 Printed value 7
Thread number :2 Printed value 7
Thread number :0 Printed value 8
Thread number :1 Printed value 8
Thread number :2 Printed value 8
Thread number :1 Printed value 9
Thread number :0 Printed value 9
Thread number :2 Printed value 9
Thread number :1 Printed value 10
Thread number :0 Printed value 10
Thread number :2 Printed value 10
Thread joind to main thread : Thread-0
Thread joind to main thread : Thread-1
Thread joind to main thread : Thread-2
Main thread ends

1 个答案:

答案 0 :(得分:2)

首先:

  

Thread实例的join()方法可用于将一个线程的执行开始“连接”到另一个线程的执行结束

这是一个误解:与启动线程无关。 Join只会这样做:正在运行的线程将等待另一个线程结束。

当您执行someThread.join()时,调用该方法的线程将等待直到someThread结束!

  

但是所有线程都是并行连接的。

是的,因为它们都完成了。

您的线程执行所有完全相同的操作,因此,除了这里或那里的几毫微秒(由于实际上写入System.out仍然有效地同步内容这一事实而使它们无效)之外,它们都需要相同的时间。 / p>

因此,当您加入第一个线程时...其他两个线程将完成。因此,对join()的第一次调用使“主”线程等待第一个线程结束,随后的调用“立即”发生,因为这些线程也已完成。

为了延迟操作,请将循环数作为MultiThreading类的参数,然后确保线程将需要不同的时间量。如果Thread-0执行10次循环,并且Thread-1执行20次循环,而Thread-2执行30次循环,您将看到每个连接实际上都在等待相应的线程结束。

长话短说:您立即开始所有线程,因此它们立即开始并行运行。稍后的join调用只是延迟了 main 线程的进程,直到每个工作线程都结束为止。