gpt4 book ai didi

java - Thread 中的 join() 方法是否保证完美工作,还是也依赖于各个 JVM?

转载 作者:行者123 更新时间:2023-12-02 10:49:20 25 4
gpt4 key购买 nike

概述

我正在学习和使用 java 中的线程。我刚刚开始研究 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();

}
}

自定义线程

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 个线程:maint1t2t3 。主线程是应用程序创建并用于运行应用程序的启动线程。

说明1

此时,只有 1 个线程正在执行:main 线程。虽然t1->t3已创建,但尚未开始执行。

说明2

这里,我们启动了t1t2,这样就有3个执行线程:t1t2main

说明3

t1.join()处,main线程(或调用线程)等待 t1 的执行完成。完成后,main 线程将继续执行。此时,t2maint1 并行执行。

说明4

main 线程再次等待执行完成,但这次是等待 t2。一旦完成,main 线程就会解除阻塞并继续。

说明5

main线程已开始执行t3,并立即等待其完成。

摘要

总体而言,此示例应用程序产生不确定的结果。无法知道 t1->t3 何时执行。产生不同的结果是正常的,因为线程每次运行可能会获得不同的 CPU 时间,导致它们在逻辑 block 中进展得更远或更远。我们所知道的是,main 线程将确保 t1t2 在启动 t3 之前完成。此外,所有线程 t1->t3 将在 main 线程完成之前完成执行。

关于java - Thread 中的 join() 方法是否保证完美工作,还是也依赖于各个 JVM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52291616/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com