gpt4 book ai didi

java - 多线程:为什么这个输出?它是确定性的吗?

转载 作者:搜寻专家 更新时间:2023-11-01 01:53:45 25 4
gpt4 key购买 nike

我正在学习编写更好的多线程程序、线程安全和确定性。我遇到了这段代码

// File Name : Callme.java
// This program uses a synchronized block.
class Callme {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println("]");
}
}

// File Name : Caller.java
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);
}
}
}
// File Name : Synch.java
public class Synch {
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");
}
}
}

产生以下输出(试了 ~100 次)

[Hello]
[World]
[Synchronized]

所以我的第一个问题是,这个输出有保证吗?我还观察到,如果我将 sleep 更改为 100,它仍然会产生相同的输出,但如果我更改 sleep到 10 输出变为

[Hello]
[Synchronized]
[World]

第二个问题是,如果有保证,为什么?最后但并非最不重要的一点是,为什么会输出?我预计会是

[Hello]
[Synchronized]
[World]

最佳答案

我认为这里发生了两件非常有趣的事情。

代码试图依靠同步块(synchronized block)来保持调用顺序一致。这有两个问题:

1) 同步块(synchronized block)不公平(请参阅 Synchronization vs Lock ),因此首先到达锁定同步块(synchronized block)的线程可能不是第一个被授予访问对象的权限。然而,根据该帖子,方法级别的同步 public synchronized void run() 将是一个公平锁(在 Java 1.5 中,而不是 Java 1.6),因此第一个等待锁的人将是第一个被授予对该对象的访问权限.

2) 即使同步块(synchronized block)是公平的,理论上,第一个线程可能不是第一个调用 run() 中的某些代码的线程([synchronized])。 [world] 实际上可以先调用它。

关于java - 多线程:为什么这个输出?它是确定性的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17199353/

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