10

我有一个包含整数值的数组,声明如下:

int data[] = new int[n];

每个值都需要处理,我将工作分成几部分,以便可以由单独的线程处理。处理过程中不会修改数组。

所有处理线程可以同时读取数组的不同部分吗?还是我必须使用锁?

换句话说:这个工作指令是线程安全的吗?

Array is created and filled
Threads are created and started
Thread 0 reads data[0..3]
Thread 1 reads data[4..7]
Thread 2 reads data[8..n]
4

6 回答 6

6

由多个线程读取数组(或任何其他集合、对象的字段等)的内容是线程安全的,前提是同时不修改数据。

如果您用要处理的数据填充数组并将其传递给不同的线程进行读取,那么数据将被正确读取,并且不会出现数据竞争。

请注意,这仅在填充数组后创建线程时才有效。如果将要处理的数组传递给一些已经存在的线程而不进行同步,则可能无法正确读取数组的内容。在这种情况下,线程获取数组引用的方法应该是同步的,因为同步块会强制线程之间的内存更新。

附带说明:使用不可变集合可能是个好主意。这样您就可以确保无法进行任何修改。我建议使用这样的包装器。检查java.util.concurrent.atomic包装,应该有可以使用的东西。

于 2013-08-15T16:47:57.490 回答
2

只要线程不修改数组中的内容,就可以从多个线程中读取数组。

于 2013-08-15T16:48:01.677 回答
0

如果您确保所有线程都在读取,那么它的线程是安全的。尽管您不应该依赖这个事实alone并尝试通过包装器使您的数组不可变。

于 2013-08-15T16:48:55.750 回答
0

当然,如果您只想阅读它,请在创建它们时将数组传递给线程。只要不修改就没有问题。

于 2013-08-15T16:49:18.890 回答
0

从数组数组中读取是线程安全的操作,但如果您正在修改数组而不是考虑使用类AtomicIntegerArray

于 2013-08-15T16:52:21.607 回答
0

考虑填充一个ConcurrendLinkedQueue并让每个线程从中拉出。这将确保不存在并发问题。

您的每个线程都会从队列顶部提取数据并进行处理。

于 2013-08-15T16:56:14.640 回答