3 回答
TA贡献1825条经验 获得超6个赞
使用锁时是否需要 volatile 修饰符以保证内存可见性?
volatile
变量只保证内存可见性,但不保证原子性。这是Java 中块volatile
和synchronized
块的主要区别之一。因此,当您使用synchronized
块时,变量不必是volatile
. 但是如果您的变量是volatile
并且对该变量执行任何复合操作,那么您需要volatile
使用锁来保护对变量的更新。
这部分是说后续同步方法调用保护同一变量将确保它对第二个线程可见吗?如果是这种情况,锁也一样吗,因为我们也可以保证订单?
是的。因为锁会给你带来可见性和原子性。
另一方面,当我们突然拥有允许 2 个线程访问该字段的写锁时会发生什么。即使在变量被解锁的情况下,整个构造是否会崩溃并且线程也永远不会保证更新它们的缓存?
如果您在同一锁上保护对变量的更新,则在任何给定时间只有一个线程可以处理该变量。所以它保证了一致性。但是如果每次都使用不同的锁来保护那个变量,那么多个线程将修改变量状态,并可能使变量状态不一致。因此,在这种情况下,可见性和原子性都得到了保证,但仍然会导致不一致。
TA贡献1797条经验 获得超6个赞
...实际上有一页说同步方法和波动性字段需要结合使用。
您可以提炼出您需要了解的有关内存可见性和synchronized
块的所有信息,并将其归结为一个简单的规则。也就是说,线程 A 在退出synchronized (o) {...}
块之前对共享变量和对象所做的任何事情都保证在线程 B 进入同一对象的synchronized (o) {...}
块时对线程 B 可见。 o
而且,正如@markspace 已经说过的,任何实现java.util.concurrent.locks.Lock
都需要以相同的方式工作。
添加回答
举报