java - 内存屏障和 java.util.concurrent.locks.Condition 示例

标签 java concurrency

我对使用 Lock 提供的 Condition 时的内存屏障有疑问。

关于 the javadoc for Condition 中提供的示例,我有一个关于使用的问题:

int putptr, takeptr, count;

难道不应该将这些属性声明为 volatile 吗?正如我从示例中理解的那样,线程可能看不到例如 count 的修改。

或者是说,当 signal() 被调用时,自获得锁以来所做的所有修改对其他线程都是可见的?很像 synchronized block 中的一些代码吗?

如果是,当调用 signal() 时,或者当调用锁上的 unlock() 时,修改是否可见?

谢谢。

编辑:我在 Lock 的 javadoc 中看到:

All Lock implementations must enforce the same memory synchronization semantics as provided by the built-in monitor lock, as described in section 17.4 of The Java™ Language Specification:

  • A successful lock operation has the same memory synchronization effects as a successful Lock action.
  • A successful unlock operation has the same memory synchronization effects as a successful Unlock action.

Unsuccessful locking and unlocking operations, and reentrant locking/unlocking operations, do not require any memory synchronization effects.

它们的意思是:“成功的锁定操作与进入synchronized block 具有相同的内存同步效果”,以及“成功的解锁操作与退出 具有相同的内存同步效果”同步 block “?

最佳答案

您应该阅读的方式是,所有发生在 lock.unlock 之前的写入对所有后续 lock.lock 都是可见的。一个正在await 的线程,当被唤醒时,本质上将执行lock.lock。因此,自上次解锁以来发生的所有写入现在都将可见。

信号 没有内存语义,因为您的后一点说明或在锁上调用 unlock() 时 是正确的。

Do they mean: "A successful lock operation has the same memory synchronization effects as entering a synchronized block", and "A successful unlock operation has the same memory synchronization effects as exiting a synchronized block"?

是的,没错!更具体地说,编译器将发出 monitorenter 和 monitorexit 字节码指令。

关于java - 内存屏障和 java.util.concurrent.locks.Condition 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15318207/

相关文章:

java - 找不到契约(Contract)附件

java - Feign Client GET 请求,从微服务中抛出 "Method Not Allowed: Request method ' POST' not supported"

java - 如何从自定义对象列表中获取特定属性值的数组

c++ - 可能同时将 *same* 值写入一个整数。我需要一个原子变量吗?

go - 无法使用书中的示例模拟死锁

java - (libgdx) 为什么我的 Sprite 渲染得这么大?

java - 无法更新远程 mysql 表

c++ - c\c++中线程和并发中一本好的编程书籍推荐

java - java代码中出现死锁

Java信号量实现和设计相关问题