使用CountDownLatch时如何正确同步/锁定

Pet*_*iuk 4 java multithreading locking blocking

它归结为一个线程通过一些服务提交工作.作业在某些TPExecutor中执行.之后,此服务检查结果并在特定条件下在原始线程中抛出异常(作业超过最大重试次数等).下面的代码片段大致说明了遗留代码中的这种情况:

import java.util.concurrent.CountDownLatch;

public class IncorrectLockingExample {

private static class Request {

    private final CountDownLatch latch = new CountDownLatch(1);

    private Throwable throwable;

    public void await() {
        try {
            latch.await();
        } catch (InterruptedException ignoredForDemoPurposes) {
        }
    }

    public void countDown() {
        latch.countDown();
    }

    public Throwable getThrowable() {
        return throwable;
    }

    public void setThrowable(Throwable throwable) {
        this.throwable = throwable;
    }

}

private static final Request wrapper = new Request();

public static void main(String[] args) throws InterruptedException {

    final Thread blockedThread = new Thread() {
        public void run() {
            wrapper.await();
            synchronized (wrapper) {
                if (wrapper.getThrowable() != null)
                    throw new RuntimeException(wrapper.getThrowable());
            }
        }
    };

    final Thread workingThread = new Thread() {
        public void run() {
            wrapper.setThrowable(new RuntimeException());
            wrapper.countDown();

        }
    };

    blockedThread.start();
    workingThread.start();

    blockedThread.join();
    workingThread.join();
}
Run Code Online (Sandbox Code Playgroud)

}

有时,(在我的盒子上不可重现,但在16核心服务器盒上发生)异常没有被报告给原始线程.我认为这是因为before-before不是强制的(例如'countDown'发生在'setThrowable'之前)并且程序继续工作(但应该失败).我很感激有关如何解决此案件的任何帮助.约束条件是:一周内发布,对现有代码库的影响最小.

wil*_*roz 6

上面的代码(现在更新)应该按预期工作,而不使用进一步的同步机制.通过使用和方法强制执行内存屏障及其相应的"先发生"关系.CountDownLatch await()countdown()

来自API文档:

一个成功的"获取"方法如Lock.lock,Semaphore.acquire,Condition.await和CountDownLatch后续动作之前"释放"同步器的方法,如Lock.unlock,Semaphore.release,和CountDownLatch.countDown发生-前行动.await在另一个线程中的同一个同步器对象上.

如果您定期处理并发让自己的拷贝的Java并发编程实践",这是Java并发圣经,将是值得它的重量你的书架上:-).