Jas*_*n S 24 java arrays concurrency
一个线程从数组的一个索引读取是否有任何并发问题,而另一个线程写入数组的另一个索引,只要索引不同?
例如(这个例子不一定推荐用于实际用途,仅用于说明我的观点)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:批评这个例子不是我的问题,我只是想知道数组访问一个索引,同时访问另一个索引,引起并发问题,想不出一个简单的例子.
Kat*_*one 15
虽然您提到的更改数组不会导致无效状态,但是当两个线程在没有同步的情况下查看非易失性整数时,您将遇到同样的问题(请参阅内存一致性错误的Java教程中的部分).基本上,问题是线程1可能在空间i中写入一个值,但不能保证何时(或如果)线程2将看到更改.
班级java.util.concurrent.atomic.AtomicIntegerArray做你想做的事.
这个例子有很多与散文问题不同的东西。
这个问题的答案是数组的不同元素是独立访问的,因此如果两个线程更改不同的元素,则不需要同步。
然而,Java 内存模型不保证(据我所知)一个线程写入的值对另一个线程可见,除非同步访问。
根据您真正想要完成的任务,很可能java.util.concurrent已经有一个课程可以为您完成它。如果没有,我仍然建议查看 的源代码ConcurrentHashMap,因为您的代码似乎正在执行与管理哈希表相同的操作。