java - Java中的数组是线程安全的吗?

标签 java arrays concurrency thread-safety

一个线程从数组的一个索引读取,而另一个线程写入数组的另一个索引,是否存在任何并发问题,只要索引不同?

例如(这个例子不一定推荐实际使用,只是为了说明我的观点)

 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/1132507/

相关文章:

java - Aspectj:从 HttpServletRresponse 获取响应正文(HTML 文本)

mysql - 在循环中使用 MySQL 输出作为 BASH 函数的输入

java - 如何处理字符串数组的别名

php - Echo PHP Swift NSDictionary 对象数组

JavaFX 版本的 ExecutorService

java - java中的慢速 map

java - 是什么原因导致该按钮崩溃?

ios - 将多上下文 CoreData 应用于基于 NSOperationQueue 的应用程序

由于 NSSQLiteErrorDomain = 1032,iOS 核心数据 saveContext 方法不成功

javascript - Node JS 变量作用域在并发请求的闭包中