[英]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.