我正在使用双重检查锁定 (DCL) 来避免在不需要时对对象进行同步。在我的情况下,我需要在某个缓冲区为空时进行同步,以让“处理线程”等待“传递线程”再次通知它 - 否则,“处理线程”将在循环中运行而不做任何有用的事情。
两个线程共享这些对象:
Object bufferLock = new Object();
Queue<Command> commands = new ConcurrentLinkedQueue<>(); // thread safe!
线程 1(“交付线程” - 填充缓冲区):
while (true)
Command command = readCommand();
commands.add(command);
synchronize (bufferLock){
bufferLock.notify(); // wake up Thread 2 (if waiting)
}
}
线程 2(“处理线程” - 清空缓冲区):
while (true){
if (commands.peek() == null){ // not creating anything here
synchronized (bufferLock){
if (commands.peek() == null){ // also not creating anything
bufferLock.wait();
}
}
}
Command command = commands.poll();
processCommand(command);
}
现在,NetBeans 出现了关于 DCL 的警告,这让我更深入地研究了这个主题,因为我不知道 DCL 的概念——我才开始自己使用它。
据我在网上阅读几篇文章了解到,使用这种模式时有一个Java错误,但所有示例都将它与延迟加载结合使用。在这些示例中,对象是在同步块中创建的。在我的同步代码中,我不创建对象。
我的代码不安全吗?NetBeans 在显示警告方面是否正确?请注意,NetBeans 之前有一个与 DCL 相关的错误,所以我有点困惑。