I observe following situation:
- Thread_1 acquires lock on sync object, do some work
- While Thread_1 hogging lock, Thread_2 tries to acquire same lock, got stuck on
synchronized
- Thread_1 releases lock, do something relatively quickly (without yielding or sleeping), then acquire same lock again
- Thread_2 remains in waiting state (of cause if scheduler do not switch to Thread_2 in this short period of time when sync object is free to tackle)
The question is: is it possible to do "honest" locking, i.e. grant lock acquiring in order requested it?
Code of test:
public class HonestMutexTest {
private Object mSync = new Object();
private Object mSleep = new Object();
private void sleep(long millis) {
try {
Thread.sleep(millis);
}
catch (InterruptedException e) {
Assert.fail();
}
}
private void normalMutexesTestIteration() {
final StringBuilder states = new StringBuilder();
final Thread firstThread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (mSync) { // 1
sleep(100);
states.append('1');
}
synchronized (mSync) {
states.append('2');
}
}
});
final Thread secondThread = new Thread(new Runnable() {
@Override
public void run() {
sleep(50);
synchronized (mSync) { // 2
states.append('3');
}
}
});
firstThread.start();
secondThread.start();
try {
firstThread.join(1000);
secondThread.join(1000);
}
catch (InterruptedException e) {
Assert.fail();
}
Assert.assertEquals(states.toString(), "123"); // what I expect here is "132"
}
@Test
public void testNormalMutexes() {
for (int i = 0; i < 10; ++i) {
normalMutexesTestIteration();
}
}
}