我正在尝试读一本学习 Java 的书。下面的代码在 Mac 和 Windows PC 上产生不同的输出。我有一台使用
OpenJDK 21.0.2
的 Macbook M2 Air,我相信这是 Mac 的最新版本,在 Windows 11 PC 上,我使用 openjdk 22 2024-03-19
我应该得到的输出在 Windows 上是正确的,但在 Mac 上是正确的我得到以下信息:
[Hello]
[World]
[Synchronized]
我不确定为什么会发生这种情况,因为理论上
synchronized
块应该在所有平台上产生相同的输出?
class Callme {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e)
{
System.out.println("Interrupted");
}
System.out.println("]"); }
}
class Caller implements Runnable {
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s) {
target = targ;
msg = s;
t = new Thread(this);
t.start();
}
// synchronize calls to call()
public void run() {
synchronized (target) { // synchronized block
target.call(msg);
}
}
}
class Synch1 {
public static void main(String args[]) {
Callme target = new Callme();
Caller ob1 = new Caller(target, "Hello");
Caller ob2 = new Caller(target, "Synchronized");
Caller ob3 = new Caller(target, "World");
// wait for threads to end
try {
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
}
我尝试在 MAC 笔记本电脑和 Windows 11 PC 上运行此代码,它在 Windows 计算机上运行良好,但在 MAC 笔记本电脑上生成的输出是无序的。我不确定为什么会发生这种情况或如何解决这个问题。
更新 我在 Windows 11 PC 上重新运行了该脚本,它执行与 MAC 相同的操作。然而,我第一次运行它时,它在 Windows 上产生了正确的输出。
你无法预测哪个线程将以什么顺序被调度很长时间。
您显然是按照按顺序启动 ob1、ob2、ob3 线程来思考的。但实际上,他们不需要按照这个顺序执行。