Java 线程中的join()方法是保证工作正常还是依赖于单个JVM?
概述 我在学习和使用java中的线程。我刚开始研究Java 线程中的join()方法是保证工作正常还是依赖于单个JVM?,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,概述 我在学习和使用java中的线程。我刚开始研究join()方法。我知道它让当前线程等待,并强制它等待thread.join()调用结束/死/终止 以下是我尝试使用的代码,用于探索功能: ThreadJoinMain package com.threeadjoin.main; import sun.nio.ch.ThreadPool; public class ThreadJoinMain { public static void main(String[] args) { Cu
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();
}
}
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();
}
}
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()
的语义。让我们研究一下下面的例子
示例应用程序
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();
}
}
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
此时,只有一个线程正在执行:main
线程。虽然已经创建了t1
->t3
,但它们尚未开始执行
解释2
在这里,我们启动了t1
和t2
,因此有3个执行线程:t1
、t2
和main
解释3
在t1.join()。完成后,main
线程继续执行。此时,t2
与main
和t1
并行执行
解释4
main
线程再次等待执行完成,但这次等待的是t2
。完成后,main
线程将解锁并继续
解释5
main
线程已开始执行t3
s,并立即等待它完成
摘要
总的来说,这个示例应用程序会产生不确定的结果。无法知道何时执行t1
->t3
。产生不同的结果是正常的,因为线程每次运行可能会获得不同的CPU时间,从而导致它们在逻辑块中前进得更远或更少。我们知道的是,main
线程将确保t1
和t2
在启动t3
之前已经完成。另外,所有线程t1
->t3
都将在main
线程完成之前完成执行。您认为thread.join()的作用是什么?因为你的代码显示你似乎不理解它的用法。具体地说,在线程启动之前加入它什么也不做:一个join()
等待它被调用的线程停止,如果它还没有启动,它就不会等待。另外:如果您想要顺序行为,请不要使用其他线程。感谢您的回复。所以我把代码改成了这个。把这两行放在t1.start()上;t2.start();在试块之前,但仍然重复运行,得到不同的结果。我在哪里犯了错误,请让我知道。我重复一遍:如果你想要顺序行为,不要使用额外的线程。您似乎仍然不明白join()
的作用。使用t1.join()
只意味着当前线程将等待t1
停止t1
和t2
仍将能够并行运行。如果您想要顺序行为,请不要使用其他线程-我肯定会将其作为建议,但不会解决我的查询。您似乎仍然不明白join()的作用我的第一行西亚斯,我正在学习。使用t1.join()只意味着当前线程将等待t1停止。t1和t2仍然能够并行运行--你确定???非常感谢。请编辑您的问题并描述您的想法t1.join()
,这样我们就可以确切地知道您的误解在哪里,我们可以给您一个很好的解释。@AbhiroopNandiRay如果这个答案对您有帮助,请务必接受它作为帮助未来用户理解的答案!