同步:线程以相同的顺序执行两个关键部分

8 java concurrency multithreading semaphore synchronisation

我有以下类型的代码:

synchronized block1 {
    //only one thread in the block
}

{lot of code where synchronization not necessary}

synchronized block2 {
    //only one thread in the block. 
    //All the threads that executed block1 before this thread should have already executed this block.
}
Run Code Online (Sandbox Code Playgroud)

每个线程首先以相同的顺序执行block1,non synchronized block和block2.

如果线程T1在线程T2之前执行block1,那么T1应该在T2之前执行block2.有两个以上的线程.

有没有办法在java中实现这一点?

Jav*_*ier 2

据我了解,关键部分 #2 必须按照与关键部分 #1 相同的顺序执行

如果线程 T1 在线程 T2 之前执行 block1,则 T1 应该在 T2 之前执行 block2。有两个以上的线程。

然后可以使用队列来确保执行顺序。

private Object lock = new Object();
private Queue<Thread> threadQueue = new ArrayDeque<>();

// /sf/ask/2264729841/
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.
    }
Run Code Online (Sandbox Code Playgroud)

但是,如果一个线程死亡/退出而没有将其自身从队列中删除,则后续线程将被无限期地阻塞。也许添加一个finally块来进行内务处理?

注意:在Nicholas Robinson 的回答中,建议使用位置顺序而不是队列,这似乎更有效。