繁体   English   中英

这里需要挥发物吗?

[英]Is volatile needed here?

在以下假设的情况下,并且出于更好地理解语言的需求, int []参考是否需要volatile?

public final class SO {

    private int[] ar = new int[10];  // is volatile needed here?
    private int idx = 0;

    public synchronized int get( int i ) {
        return ar[i];
    }

    public synchronized void append( final int val ) {
        if ( idx == ar.length ) {
            // array is too small, let's grow it
            final int[] prev = ar;
            ar = new int[ar.length+ar.length*20/100]
            System.arrayCopy(prev, 0, ar, 0, prev.length);
        }
        ar[idx++] = val;
    }

}

检索int的唯一方法是通过同步方法,而修改int [] (包括创建新的int [] )的唯一方法也是通过同步方法来完成。

我不需要添加任何其他同步权吗?

不,不需要volatile ,因为它只能在同步方法内部访问,因此它已经是线程安全的。 您的代码中不需要进一步的线程安全性。

就像您说的那样,因为int受类锁保护-但它会慢一些,因为写入和读取访问相互阻塞。 (有关更快速的方法,请参见CopyOnWriteList实现)

很好,除非您的值在没有同步的情况下在其他位置访问。

顺便说一句,如果您确实使ar volatile而不是使用同步方法,那么您也需要使idx易失性。 但是,这仍然不会是因为两个不同的线程运行足够的同步append在同一时间可以肆虐。

实际上,使用volatile数组还有另一个问题:更改数组中的值不会触发缓存同步。 仅重新分配阵列(就像创建更大的阵列时一样)会触发缓存刷新。

根据具有可变性的java lang规范 ,为线程(从主内存中读取/写入)添加了严格的规则,在这一点上使用了同步放松。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM