只要索引不同,一个线程从数组的一个索引读取,而另一个线程写入数组的另一个索引,是否存在任何并发问题?
例如(这个例子不一定推荐实际使用,只是为了说明我的观点)
class Test1
{
static final private int N = 4096;
final private int[] x = new int[N];
final private AtomicInteger nwritten = new AtomicInteger(0);
// invariant:
// all values x[i] where 0 <= i < nwritten.get() are immutable
// read() is not synchronized since we want it to be fast
int read(int index) {
if (index >= nwritten.get())
throw new IllegalArgumentException();
return x[index];
}
// write() is synchronized to handle multiple writers
// (using compare-and-set techniques to avoid blocking algorithms
// is nontrivial)
synchronized void write(int x_i) {
int index = nwriting.get();
if (index >= N)
throw SomeExceptionThatIndicatesArrayIsFull();
x[index] = x_i;
// from this point forward, x[index] is fixed in stone
nwriting.set(index+1);
}
}
编辑: 批评这个例子不是我的问题,我只是想知道数组访问一个索引,同时访问另一个索引,是否会造成并发问题,想不出一个简单的例子。
最佳答案
虽然您不会像您提到的那样通过更改数组获得无效状态,但您会遇到与两个线程在没有同步的情况下查看非 volatile 整数时发生的相同问题(请参阅 Java 教程中关于 Memory Consistency Errors 的部分) .基本上,问题在于线程 1 可能会在空间 i 中写入一个值,但无法保证线程 2 何时(或是否)会看到更改。
类(class)java.util.concurrent.atomic.AtomicIntegerArray
做你想做的事。
关于java - 数组在 Java 中是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53399876/