gpt4 book ai didi

java - 是否保证线程将按照它们在 Java 中被 wait() 暂停/阻塞的顺序恢复?

转载 作者:行者123 更新时间:2023-11-29 04:21:32 26 4
gpt4 key购买 nike

假设我的程序使用三个线程。前两个线程使用 wait() 被阻塞,然后第三个线程出现并恢复它们。当第三个线程释放这两个线程时,它会在这两个线程之间创建竞争条件(如果我错了请纠正我)。这是我写的一个程序来说明这一点:

class Callee {
static boolean doBlock = true;
void callMe (int index) throws InterruptedException {
//suspend the first two threads
if (index < 3 && doBlock) {
wait();
}

System.out.println("The index is: " + index);

//let the third thread resume both of them
if (index == 3) {
doBlock = false;
notifyAll();
}
}
}

class Caller implements Runnable {

final int threadIndex;
final Thread thread;
final Callee callee;

Caller(int index, Callee c) {
threadIndex = index;
callee = c;
thread = new Thread(this);
thread.start();
}

@Override
public void run() {
synchronized (callee) {
try {
callee.callMe(threadIndex);

} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}

public class App {

public static void main(String[] args) throws InterruptedException {
Callee c = new Callee();

Caller caller1 = new Caller (1, c);
Caller caller2 = new Caller (2, c);
Caller caller3 = new Caller (3, c);

caller1.thread.join();
caller2.thread.join();
caller3.thread.join();
}
}

每次我在 Windows 机器上运行上述程序时,我都会得到一致的输出:

索引是:3
指数是:1
索引为:2

请注意,第一个线程在第二个线程之前被释放。另请注意,我没有为这些线程中的任何一个设置优先级。我至少运行了十次,但结果没有改变。我很好奇是我的操作系统问题还是 Java 总是恢复最先被阻塞的线程?

最佳答案

简答

不,不能保证它们会按顺序恢复,因此您不应该基于此构建任何逻辑,即使该行为已被多人多次验证,但您有一个很好的想法,即询问而不是仅仅假设.

长答案

可能发生的情况是,这就是线程在 Windows 上的具体行为方式;如果线程完全由 SO 本身处理,它甚至可能是特定于您的特定 Windows 版本的行为。在这种情况下,由于 Java 在多个操作系统上运行,并且每个操作系统的行为可能不同,因此 Java 无法保证在所有环境中的行为,因此不对此做出任何 promise 。

它也可能只是特定版本的 JVM 的一种行为,而 Sun/Oracle 从来不想 promise 特定的行为,这意味着即使这种行为在当前的 JVM 版本中是不变的,因为它是绝不是正式“契约(Contract)”的一部分,他们可以保留随时更改契约(Contract)的权利,恕不另行通知。

在任何一种情况下,如果您决定在它之上构建逻辑,可能会发生的情况是代码根本无法在另一个操作系统上正常工作,或者更好的是,在操作系统更新或 JVM 更新后停止正常工作(甚至次要的)。

这方面的一个例子发生在我几年前工作过的一家公司;它曾经是 Oracle(RDBMS)过去常常根据你的 GROUP BY 标准自动排序你的结果,如果你没有指定任何(它从来不是 SQL 标准的一部分,也没有在任何 Oracle 文档中指定,每个人都注意到它像那样工作)......以他们无穷的智慧,许多人开始只是跳过 ORDER BY 子句,如果他们使用 group by 的话。然后出现了一个新的 Oracle 版本(可能是 9i 或 10g),他们只是停止了对结果的自动排序,这导致数百万 $$$ 被浪费在检查所有应用程序以检查代码然后重新进行测试(测试是当然不是自动的)。

关于java - 是否保证线程将按照它们在 Java 中被 wait() 暂停/阻塞的顺序恢复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48844730/

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