【问题标题】:Full volatile Visibility Guarantee完全不稳定的可见性保证
【发布时间】:2019-12-25 09:43:06
【问题描述】:

我正在阅读一篇关于 Java Volatile 关键字的文章,有一些问题。 click here

public class MyClass {
    private int years;
    private int months
    private volatile int days;


    public void update(int years, int months, int days){
        this.years  = years;
        this.months = months;
        this.days   = days;
    }
}

udpate()方法写入三个变量,其中只有days是volatile的。

完整的 volatile 可见性保证意味着,当一个值被写入 days 时,线程可见的所有变量也会被写入主内存。这意味着,当一个值写入天时,年和月的值也会写入主存。

那么,“线程可见的所有变量”是什么意思? 是指线程栈中的所有变量吗? “线程可见”是什么意思?我怎么知道线程可以看到月份和年份?

【问题讨论】:

    标签: java multithreading volatile


    【解决方案1】:

    都是关于happens-before relationship

    这种关系只是保证内存写入一个 特定语句对另一个特定语句可见。

    1. 在同一个线程中,

          this.years  = years;
          this.months = months;
      

      happens-before:

          this.days   = days;
      
    2. 在不同的线程中,volatile变量的写入 happens-before 读取volatile的读者线程 变量。

    并且,happens-before 关系具有transitivity。当reader线程看到volatile变量days的新值时,也可以读取yearsmonths的新值。

    【讨论】:

    • 请注意,这(如果它是正确的)仍然是一个非常弱的保证。它说您会看到一些更新,但绝对不是说您在读取/使用数据时总是会看到一致的年/月/日三元组。最突出的是,当读取天、月、年时(将 volatile 读取为第一个语句?),有人可能在此期间调用了 update(),而您可能看到该调用的结果在您的一个或多个领域。为了完全一致,您需要使用适当的同步/锁定。
    【解决方案2】:

    唯一保证这段代码能给你的,是如果某个线程观察写入days的值,它也会观察写入的值yearsmonths - 如果没有 update 再次调用;这些不是原子的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-05
      • 2011-08-10
      • 2019-11-16
      相关资源
      最近更新 更多