可见性
Visibility这玩意儿很微妙,很容易违反直觉。要在多线程之间读写内存保证可见性,需要使用同步:always use the proper synchronization whenever data is shared across threads.
Stale Data
public class MutableInteger {
private int value;
public int get() { return value; }
public void set(int value) { this.value = value; }
}
对于这个程序,即使对setter方法加上同步也是不够的,其它读的线程依然可能读到修改之前或之后的数据。
对于64位的数字型变量,double或long,则不止是stale data的问题,因为JVM会将64位的读写操作分成两个32位的操作。所以有可能读到完全错误的数据。
锁和可见性
可以用锁来保证可见性。Locking is not just about mutual exclusion; it is also about memory visibility. To ensure that all threads see the most up-to-date values of shared mutable variables, the reading and writing threads must synchronize on a common lock.
Volatile变量
也可以用volatile来保证可见性。要使用volatile变量,必须满足下面三个条件
- Writes to the variable do not depend on its current value, or you can ensure that only a single thread ever updates the value;
- The variable does not participate in invariants with other state variables; and
- Locking is not required for any other reason while the variable is being accessed.
锁既能保证原子性又能保证可见性,而volatile只能保证可见性。volatile最常用在表示完成、中断或者状态这样的标志位上。volatile不能保证像count++这种计数器的作用,除非能肯定只有一个线程去更新它。
本文深入探讨了Java内存可见性概念及其解决方式,重点介绍了如何使用Volatile关键字确保多线程环境下数据的一致性和正确性。通过实例分析,揭示了同步和Volatile在确保数据一致性和原子性上的区别与联系。
805

被折叠的 条评论
为什么被折叠?



