不安全的发布并发java [英] Unsafe publication concurrency java

查看:232
本文介绍了不安全的发布并发java的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java并发在实践中给出了不安全发布的例子

Java concurrency in practice book has given an example for unsafe publication

public class Holder 
{
    private int n;
    public Holder(int n)
    {
        this.n = n; 
    }
    public void assertSanity() 
    {
        if (n != n)
            throw new AssertionError("This statement is false.");
    }
}

上面的代码似乎是线程安全的。如果n是公共变量,它不会是线程安全的。书的例子错了吗?

The above code seems to be thread safe. It would not be thread safe if n is public variable. Is the book example wrong?

推荐答案

安全发布是关于内存可见性。内存可见性的概念比其他线程安全问题(如竞争条件)有点棘手。

Safe publication is about memory visibility. The concept of memory visibility is a bit trickier than other thread safety issues such as race conditions.

内存可见性问题出现在一个线程以一定顺序执行的操作似乎

Memory visibility issues arise when actions performed by one thread in certain order appear to be performed in different order for another thread (it may be caused by optimizations made by compiler or CPU).

在您的情况下:

// Thread A
h = new Holder(42);

// Thread B
h.assertSanity();

对于线程A, n h 之前。

For Thread A, n is certainly initialized before h.

但是在安全发布时,不能保证对于线程B是一样的。线程B可以看到 h 在初始化状态,但 n 将不会被初始化。此外,线程B观察到的 n 的状态可能在 n!= n 的评估期间改变,导致 assertSanity()抛出一个异常。

But in absense of safe publication it's not guaranteed to be the same for Thread B. Thread B may see h in initialized state, but n won't be initialzed yet. Moreover, the state of n as observed by Thread B may change during evaluation of n != n, causing assertSanity() to throw an exception.

注意,这个问题不是保证在所有情况下发生的。你可能永远不会看到这种情况,但是Java内存模型不能保证正确性。

Note that this problem is not something that is guaranteed to happen in all cases. You will probably never see this happening, but Java Memory Model doesn't guarantee correctness in this case nonetheless.

这篇关于不安全的发布并发java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆