gpt4 book ai didi

java - 同步锁由最短等待线程获取

转载 作者:行者123 更新时间:2023-12-03 11:18:01 26 4
gpt4 key购买 nike

我知道synchronize(LOCK)是不公平的,这意味着不能保证等待时间最长的线程会赢得锁。然而,在我下面的小实验中,似乎锁是由最短的等待线程获取的......

public class Demo {
public static final Object LOCK = new Object();

public void unfairDemo(){

// Occupy the lock for 2 sec
new Thread(() -> {
synchronized (LOCK) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();

// Spawn 10 new threads, each with 100ms interval, to see which can win the lock
// If lock is fair then it should print the i in asc order
for (var i = 0; i < 10; i++) {
int finalI = i;
new Thread(() -> {
System.out.println("Added " + String.valueOf(finalI) + "th element to wait for lock");

synchronized (LOCK) {
System.out.println("I got the lock, says " + String.valueOf(finalI) + "-th thread");
}
}).start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

try {
// Keep the program alive
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
运行不公平演示()打印以下内容:
Added 0th element to wait for lock
Added 1th element to wait for lock
Added 2th element to wait for lock
Added 3th element to wait for lock
Added 4th element to wait for lock
Added 5th element to wait for lock
Added 6th element to wait for lock
Added 7th element to wait for lock
Added 8th element to wait for lock
Added 9th element to wait for lock
I got the lock, says 9-th thread
I got the lock, says 8-th thread
I got the lock, says 7-th thread
I got the lock, says 6-th thread
I got the lock, says 5-th thread
I got the lock, says 4-th thread
I got the lock, says 3-th thread
I got the lock, says 2-th thread
I got the lock, says 1-th thread
I got the lock, says 0-th thread
我预计顺序会被打乱,但无论我如何尝试,结果都是相反的。我在这里做错了什么?

最佳答案

来源很多,比如this ,这已经表明不应该假设线程获取锁的顺序。但这并不意味着必须打乱订单。
它可能至少取决于 JVM 实现。例如,this document关于热点 说:

Contended synchronization operations use advanced adaptive spinning techniques to improve throughput even for applications with significant amounts of lock contention. As a result, synchronization performance becomes so fast that it is not a significant performance issue for the vast majority of real-world programs.

...

In the normal case when there's no contention, the synchronization operation will be completed entirely in the fast-path. If, however, we need to block or wake a thread (in monitorenter or monitorexit, respectively), the fast-path code will call into the slow-path. The slow-path implementation is in native C++ code while the fast-path is emitted by the JITs.


我不是 HotSpot 的专家(也许其他人可以提供更权威的答案),但基于 C++ code ,看起来竞争线程将被推送到 LIFO 结构上,这可以解释您观察到的类似堆栈的顺序:
// * Contending threads "push" themselves onto the cxq with CAS
// and then spin/park.
...
// Cxq points to the set of Recently Arrived Threads attempting entry.
// Because we push threads onto _cxq with CAS, the RATs must take the form of
// a singly-linked LIFO.

关于java - 同步锁由最短等待线程获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66388016/

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