这个线程连接代码是啥意思?
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。
-
主线程创建并启动
t1
和t2
线程。两个线程开始并行运行。
主线程调用t1.join()
等待t1
线程完成。
t1
线程完成,t1.join()
方法在主线程中返回。请注意,t1
可能在调用 join()
之前已经完成,在这种情况下,join()
调用将立即返回。
主线程调用t2.join()
等待t2
线程完成。
t2
线程完成(或者它可能在 t1
线程完成之前完成)并且 t2.join()
方法在主线程中返回。
了解t1
和t2
线程一直在并行运行很重要,但是启动它们的主线程需要等待它们完成才能继续。这是一种常见的模式。此外,t1
和/或t2
可能在主线程调用join()
之前完成。如果是这样,那么join()
不会等待,而是会立即返回。
t1.join()
表示导致 t2 停止直到 t1 终止?
没有。正在调用t1.join()
的main 线程将停止运行并等待t1
线程完成。 t2
线程并行运行,完全不受t1
或t1.join()
调用的影响。
就 try/catch 而言,join()
throws InterruptedException
意味着调用 join()
的主线程本身可能被另一个线程中断。
while (true)
在while
循环中加入连接是一种奇怪的模式。通常,您会先进行第一次连接,然后再进行第二次连接,以在每种情况下适当地处理 InterruptedException
。无需将它们置于循环中。
【讨论】:
+1 这是一个非常奇怪的模式,可能可以删除。 如果 t1 先完成,然后 t2 完成。这似乎是一个连续的过程。一个线程首先完成,然后另一个。多线程有什么意义? 因为t1
和t2
可以并行运行。只是main
需要它们都完成才能继续。这是@user697911 的典型模式。
while
循环存在是因为(我猜)它想在join()
调用被中断时重试?我当然不会那样写@user697911。
循环用于确保t1
和t2
都完成。 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
也是如此。无论是谁启动了t1
或t2
线程(在本例中为main
方法),main 都会等到t1
和t2
完成他们的任务。
但是,需要注意的重要一点是,t1
和 t2
本身可以并行运行,而与 t1
和 t2
上的加入调用顺序无关。必须等待的是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 走出等候室,继续执行。
【讨论】:
嗯,这是否意味着我可以将其视为 javascript 的await
函数?哈哈【参考方案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 循环。
【讨论】:
以上是关于这个线程连接代码是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章