As I understand Critical Section #2 MUST be executed in the same order as Critical Section #1
If thread T1 executes block1 before thread T2, then T1 should execute block2 before T2. There are more than two threads.
Then a Queue might be used to ensure the order of execution.
private Object lock = new Object();
private Queue<Thread> threadQueue = new ArrayDeque<>();
// https://mcmap.net/q/1374837/-synchronization-threads-execute-two-critical-sections-in-same-order
public void executeCriticalSectionsInOrder() throws InterruptedException {
// Critical Section #1
synchronized (lock){
// synchronized code #1
// Add self to queue
threadQueue.add(Thread.currentThread());
}
// {lot of code where synchronization not necessary}
// Critical Section #2
synchronized (lock) {
//All the threads that executed block1 before this thread should have already executed this block.
// Wait turn
Thread t = threadQueue.element(); // Do not remove until it is self
while (t != Thread.currentThread()) {
lock.wait();
// After sleep try again
t = threadQueue.element();
}
// Verified own turn. Update status
threadQueue.remove();
// synchronized code #2
lock.notifyAll(); // Awake any waiting thread after exiting section.
}
However If one thread dies/exits without removing itself from the queue, then following threads will be blocked indefinetely. Maybe add a finally block to do the housekeeping?
Note: In Nicholas Robinson's answer a position order was suggested instead of a queue, which seems slightly more efficient.
block2()
inside block1? – Rebbasynchronized(this) {...}
or are they different methods? – Rebba