I know that the synchronize(LOCK) is unfair, which means there is no guarantee that the longest waiting thread will win the lock. However in my little experiment below it seems that the lock was acquired by shortest waiting threads...
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();
}
}
}
Running unfairDemo() prints the following:
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
I expected that the order would be scrambled, but no matter how I tried the results are in reverse order. What did I do wrong here?