在Java的上下文中,我有这样的代码,
MyObject[] array;
在不同的主题中,我有一个像这样的代码
array[i] = new MyObject(val);
如果我确保每个线程使用不同的“i
”值,那么我是否需要同步上述语句来处理竞争条件?
答案 0 :(得分:3)
如果两个线程可以同时读取和修改同一个变量,则竞争条件只是一个问题。
只要您确定每个线程使用不同的索引范围,并且未重新定义基础数组,那么将每个单元视为不同的变量应该是安全的。因此,每个线程都在一组单独的变量上工作,你就不会遇到竞争条件。
话虽如此,请确保您在使用指数时确实没有重叠 - 这通常比看上去更复杂。
此外,您必须确保没有两个单元格映射到对象 - 如果您从两个线程修改同一个对象(而不仅仅是对它的引用),您可能会遇到竞争条件。
答案 1 :(得分:3)
也许。如果每个任务都写入数组中的其他位置,则它们不会覆盖彼此的输出。这样才有用。
但是,在最终处理数组时,您可能会面临一个问题,因为Java在将值写入内存时不会提供保证。优化器可能决定很晚写(或者为时已晚)。因此,您应该创建数组volatile
,这意味着访问其中的值时不会发生缓存。
答案 2 :(得分:2)
如果您完全确定每个线程将始终访问不同的索引,那么您不需要同步这些访问。
但是你确实需要确保将数组的 引用正确发布到不同的线程 - 实际上这通常意味着引用必须是{ {3}}或final。
答案 3 :(得分:0)
这里有三个谨慎的兴趣点。
数组变量本身:将变量array
声明为volatile
或final
(或同步array
)非常重要保证线程访问相同的实例数组。如果不是,可以采取以下措施:
array
作为新的Array对象array
,但获取NullPointerExceptoin
因为它还没有看到线程A将新数组分配给array
。不好。
数组引用MyObject实例(以及似乎是Venkatraman的实际问题):array
变量本身已正确同步,然后是,两个线程可以访问安全的数组中的不同元素。一旦子线程完成了它正在做的任何事情,那么'master'线程将希望同步数组以确保它在使用之前获得子数组元素的最终状态
MyObject实例本身,但这似乎超出了问题的范围