如果 join 阻塞了主线程,为什么它不阻塞在循环中?
If join blocks the main thread, why it doesn't block in loop?
Thread 实例的 join() 方法可用于 "join" 一个线程执行的开始到另一个线程执行的结束,这样线程将不会启动 运行ning 直到另一个线程已结束。如果在 Thread 实例上调用 join(),当前 运行ning 线程将阻塞,直到 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");
}
}
在上面的代码中,如果第一个线程加入,那么主线程应该被阻塞,不应该让其他线程加入(直到加入的线程完成运行方法的执行)。但是所有线程都是并行连接的。输出类似于 -
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
首先:
The join() method of a Thread instance can be used to "join" the start of a thread's execution to the end of another thread's execution
这是一个误解:这与 starting 线程无关。 Join 仅执行此操作:运行 线程将等待另一个线程结束。
当您执行 someThread.join()
时,调用该方法的线程将等待 someThread 结束!
But all the threads are joined in parallel.
是的,因为它们都完成了。
你的线程做所有完全相同的事情,所以除了这里或那里的几纳秒(由于写入 System.out 有效地同步东西这一事实,它们大部分是无效的)它们都需要相同的数量时间。
所以当您加入第一个线程时...其他两个线程将完成。因此第一次调用 join()
使 "main" 线程等待第一个线程结束,随后的调用发生 "instantly",因为这些线程也已完成。
为了延迟事情,将循环次数作为您的 MultiThreading
class 的参数,然后确保您的线程需要不同的时间量。如果 Thread-0 执行 10 次循环,Thread-1 执行 20 次,而 Thread-2 执行 30 次,您将看到每个连接实际上都在等待相应的线程结束。
长话短说:您立即启动所有线程,因此它们立即并行启动运行。后面的 join 调用只是延迟 main 线程的运行,直到每个工作线程都结束。
Thread 实例的 join() 方法可用于 "join" 一个线程执行的开始到另一个线程执行的结束,这样线程将不会启动 运行ning 直到另一个线程已结束。如果在 Thread 实例上调用 join(),当前 运行ning 线程将阻塞,直到 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");
}
}
在上面的代码中,如果第一个线程加入,那么主线程应该被阻塞,不应该让其他线程加入(直到加入的线程完成运行方法的执行)。但是所有线程都是并行连接的。输出类似于 -
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
首先:
The join() method of a Thread instance can be used to "join" the start of a thread's execution to the end of another thread's execution
这是一个误解:这与 starting 线程无关。 Join 仅执行此操作:运行 线程将等待另一个线程结束。
当您执行 someThread.join()
时,调用该方法的线程将等待 someThread 结束!
But all the threads are joined in parallel.
是的,因为它们都完成了。
你的线程做所有完全相同的事情,所以除了这里或那里的几纳秒(由于写入 System.out 有效地同步东西这一事实,它们大部分是无效的)它们都需要相同的数量时间。
所以当您加入第一个线程时...其他两个线程将完成。因此第一次调用 join()
使 "main" 线程等待第一个线程结束,随后的调用发生 "instantly",因为这些线程也已完成。
为了延迟事情,将循环次数作为您的 MultiThreading
class 的参数,然后确保您的线程需要不同的时间量。如果 Thread-0 执行 10 次循环,Thread-1 执行 20 次,而 Thread-2 执行 30 次,您将看到每个连接实际上都在等待相应的线程结束。
长话短说:您立即启动所有线程,因此它们立即并行启动运行。后面的 join 调用只是延迟 main 线程的运行,直到每个工作线程都结束。