Thread中的join()方法是否可以完美地工作,还是依赖于单个JVM?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Thread中的join()方法是否可以完美地工作,还是依赖于单个JVM?相关的知识,希望对你有一定的参考价值。
概观
我正在学习和使用java中的Threads。我刚开始调查join()
方法。我知道它允许当前线程并强制它等待,直到thread.join()
调用结束/死/终止。
这是我试图用来探索功能的代码:
ThreadJoinMain
package com.threeadjoin.main;
import sun.nio.ch.ThreadPool;
public class ThreadJoinMain {
public static void main(String[] args) {
CustomThreadOne threadOne = new CustomThreadOne();
Thread t1 = new Thread(threadOne);
t1.setName("Thread 1");
t1.setPriority(10);
Thread t2 = new Thread(threadOne);
t2.setName("Thread 2");
/*Thread t3 = new Thread(threadOne);
t3.setName("Thread 3");*/
try{
t1.join();
//t2.join();
}
catch (InterruptedException e){
e.printStackTrace();
}
t1.start();
t2.start();
//t3.start();
}
}
CustomThreadOne
package com.threeadjoin.main;
public class CustomThreadOne implements Runnable{
@Override
public void run() {
for(int i = 0; i < 10; i ++){
System.out.println("Inside thread: " +
Thread.currentThread().getName() + " value: " + i);
}
}
}
大多数时候它给出了这样的令人满意的结果:
Inside thread: Thread 1 value: 0
Inside thread: Thread 1 value: 1
Inside thread: Thread 1 value: 2
Inside thread: Thread 1 value: 3
Inside thread: Thread 1 value: 4
Inside thread: Thread 1 value: 5
Inside thread: Thread 1 value: 6
Inside thread: Thread 1 value: 7
Inside thread: Thread 1 value: 8
Inside thread: Thread 1 value: 9
Inside thread: Thread 2 value: 0
Inside thread: Thread 2 value: 1
Inside thread: Thread 2 value: 2
Inside thread: Thread 2 value: 3
Inside thread: Thread 2 value: 4
Inside thread: Thread 2 value: 5
Inside thread: Thread 2 value: 6
Inside thread: Thread 2 value: 7
Inside thread: Thread 2 value: 8
但是,如果我连续运行此代码而不进行任何更改或强行重新构建它,有时(尽管很少)输出如下:
Inside thread: Thread 1 value: 0
Inside thread: Thread 2 value: 0
Inside thread: Thread 1 value: 1
Inside thread: Thread 2 value: 1
Inside thread: Thread 1 value: 2
Inside thread: Thread 2 value: 2
Inside thread: Thread 1 value: 3
Inside thread: Thread 2 value: 3
Inside thread: Thread 1 value: 4
Inside thread: Thread 2 value: 4
Inside thread: Thread 1 value: 5
Inside thread: Thread 2 value: 5
Inside thread: Thread 1 value: 6
Inside thread: Thread 1 value: 7
Inside thread: Thread 1 value: 8
Inside thread: Thread 2 value: 6
Inside thread: Thread 1 value: 9
Inside thread: Thread 2 value: 7
Inside thread: Thread 2 value: 8
Inside thread: Thread 2 value: 9
或这个:
Inside thread: Thread 2 value: 0
Inside thread: Thread 1 value: 0
Inside thread: Thread 2 value: 1
Inside thread: Thread 1 value: 1
Inside thread: Thread 2 value: 2
Inside thread: Thread 1 value: 2
Inside thread: Thread 2 value: 3
Inside thread: Thread 1 value: 3
Inside thread: Thread 2 value: 4
Inside thread: Thread 1 value: 4
Inside thread: Thread 2 value: 5
Inside thread: Thread 1 value: 5
Inside thread: Thread 2 value: 6
Inside thread: Thread 1 value: 6
Inside thread: Thread 2 value: 7
Inside thread: Thread 1 value: 7
Inside thread: Thread 2 value: 8
Inside thread: Thread 1 value: 8
Inside thread: Thread 2 value: 9
Inside thread: Thread 1 value: 9
这里有什么我想念的吗?
概观
好问题!是!它保证按预期工作,并且不依赖于JVM。但是,我在源代码中看到了很多混淆点,因此我将使用类似的应用程序逐步介绍join()
上的语义。让我们研究下面的例子。
示例应用
public static void main(String[] args) {
// Create threads t1 -> t3
Thread t1 = new Thread(threadOne);
t1.setName("Thread 1");
Thread t2 = new Thread(threadOne);
t2.setName("Thread 2");
Thread t3 = new Thread(threadOne);
t3.setName("Thread 3");
//////////// Explanation 1 /////////////
t1.start(); // Begin execution of t1
t2.start(); // Begin execution of t2
//////////// Explanation 2 /////////////
try {
t1.join(); // Force main thread to wait for t1
//////////// Explanation 3 /////////////
t2.join(); // Force main thread to wait for t2
//////////// Explanation 4 /////////////
t3.start(); // Begin execution of t3
t3.join(); // Force main thread to wait for t3
//////////// Explanation 5 /////////////
} catch (InterruptedException e) {
e.printStackTrace();
}
}
这里,实际上有4个线程存在于此代码中:main
,t1
,t2
,t3
。主线程是应用程序创建并用于运行应用程序的起始线程。
解释1
此时,只有1个线程正在执行:main
线程。尽管t1
-> t3
已经创建,但它们尚未开始执行。
解释2
在这里,我们已经启动了t1
和t2
,因此有3个执行线程:t1
,t2
和main
。
解释3
在t1.join()
,main
线程(或调用线程)等待t1
的执行完成。完成后,main
线程继续执行。在这一点上,t2
与main
和t1
并行执行。
解释4
main
线程再次等待执行完成,但这次是t2
。一旦完成,main
线程将被解锁并继续。
说明5
main
线程已经开始执行t3
s,并立即等待它完成。
摘要
总的来说,这个示例应用程序产生不确定的结果。无法知道何时会执行t1
-> t3
。具有不同的结果是正常的,因为线程可能每次运行获得不同的CPU时间,从而导致它们在其逻辑块中进一步或更远。我们所知道的是,main
线程将确保t1
和t2
在开始t3
之前完成。此外,所有线程t1
-> t3
将在main
线程完成之前完成执行。
以上是关于Thread中的join()方法是否可以完美地工作,还是依赖于单个JVM?的主要内容,如果未能解决你的问题,请参考以下文章
Thread.join() 在 Dining Philosophers 实现中无法正常工作
是否可以在没有 pthread_join() 的情况下使用 pthread?