Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何检测和处理多线程环境中访问的java列表中的冲突?_Java_Multithreading_List - Fatal编程技术网

如何检测和处理多线程环境中访问的java列表中的冲突?

如何检测和处理多线程环境中访问的java列表中的冲突?,java,multithreading,list,Java,Multithreading,List,我有一个汽车网格,每辆车在网格上有一个独特的位置(x,y),谁可以移动。我有一个中介,它引用了这些汽车的列表,应该控制汽车在网格上的移动,特别是控制一次只有一辆汽车可以有相同的位置(x,y)(避免碰撞) 在mediator中,可以注册车辆(Listadd),为了避免碰撞,每次在通知车辆移动之前,都必须迭代车辆列表,以检查其当前位置。当然,我们在一个多线程环境中,在一个逐车线程模型中,这意味着一个线程可以潜在地注册一辆新车,而另一个线程可以同时移动一辆现有的车,如果两辆车的位置相同(x,y),则会

我有一个汽车网格,每辆车在网格上有一个独特的位置(x,y),谁可以移动。我有一个中介,它引用了这些汽车的列表,应该控制汽车在网格上的移动,特别是控制一次只有一辆汽车可以有相同的位置(x,y)(避免碰撞)

在mediator中,可以注册车辆(
List
add),为了避免碰撞,每次在通知车辆移动之前,都必须迭代车辆列表,以检查其当前位置。当然,我们在一个多线程环境中,在一个逐车线程模型中,这意味着一个线程可以潜在地注册一辆新车,而另一个线程可以同时移动一辆现有的车,如果两辆车的位置相同(x,y),则会导致碰撞

要处理汽车列表,我看到了两种解决方案:
CopyOnWriteArrayList
和一个简单的
ArrayList
,其中包含ReentrantLock/Condition对象

如果我理解清楚的话,
CopyOnWriteArrayList
是线程安全的,但只提供了汽车列表的副本,它并不总是底层阵列的最新版本。所以,我可能会使用它来获得碰撞。 否则,我可以使用带有ReentrantLock的简单的
ArrayList
来锁定寄存器和handleMove方法,并使用Condition对象在检测到潜在冲突时使当前线程等待

在我看来,我应该使用带有锁的
ArrayList
。 您是否确认
CopyOnWriteArrayList
不适用于这种情况?你还有别的解决办法吗


提前感谢。

您似乎需要一个同步列表。您可以使ArrayList与Collections.synchronizedList(ArrayList)同步。并确保在迭代列表时没有线程更改列表

   List list = Collections.synchronizedList(new ArrayList());
       ...
   synchronized (list) {
       Iterator i = list.iterator(); // Must be in synchronized block
       while (i.hasNext())
           foo(i.next());
   }

似乎您需要一个同步列表。您可以使ArrayList与Collections.synchronizedList(ArrayList)同步。并确保在迭代列表时没有线程更改列表

   List list = Collections.synchronizedList(new ArrayList());
       ...
   synchronized (list) {
       Iterator i = list.iterator(); // Must be in synchronized block
       while (i.hasNext())
           foo(i.next());
   }

?synchronized基本上是做与使用lock相同的事情。好的。但我想确定的是,我是否可以从潜在的解决方案中删除CopyOnWriteArrayList。我编辑我的问题。谢谢。据我所知,
CopyOnWriteArrayList
为您提供了一个线程安全快照以供迭代,并且在迭代时不会反映对原始列表的并发更改(因此,没有机会抛出
ConcurrentModificationException
)。如果在迭代快照时不关心原始列表中发生了什么,那么它似乎很有用。所以它不适合你的需要@完全正确。那么,您认为带锁的ArrayList足够了吗?我不明白evgeniy Dorofev命题是否要使用Collections.synchronizedList,如果我还必须使用同步块的话。ArrayList+ReentrantLock对我来说已经足够了。@rico如果您使用
ReentrantLock
进行自己的锁定,那么就没有必要使用
synchronizedList
;只需使用一个普通的
ArrayList
,但记住在访问它的任何地方都要执行所有锁定。synchronized基本上与使用lock做相同的事情。好的。但我想确定的是,我是否可以从潜在的解决方案中删除CopyOnWriteArrayList。我编辑我的问题。谢谢。据我所知,
CopyOnWriteArrayList
为您提供了一个线程安全快照以供迭代,并且在迭代时不会反映对原始列表的并发更改(因此,没有机会抛出
ConcurrentModificationException
)。如果在迭代快照时不关心原始列表中发生了什么,那么它似乎很有用。所以它不适合你的需要@完全正确。那么,您认为带锁的ArrayList足够了吗?我不明白evgeniy Dorofev命题是否要使用Collections.synchronizedList,如果我还必须使用同步块的话。ArrayList+ReentrantLock对我来说已经足够了。@rico如果您使用
ReentrantLock
进行自己的锁定,那么就没有必要使用
synchronizedList
;只需使用一个普通的
ArrayList
,但记住在访问它的任何地方都要执行所有锁定。2注释:1。为什么它比使用CopyOnWriteArrayList更好?2.如果对列表使用同步块,为什么不使用简单的ArrayList呢?如果我理解的很好,那么您的解决方案相当于使用CopyOnWriteArrayList和用于读取访问的补充锁,以确保具有最新版本的基础阵列。这就是为什么我认为使用带锁的ARAYLIST是足够的,因为我不需要向同步添加同步。1。据我所知,您不希望线程在迭代2时插入元素。同步块可防止在迭代期间更改列表,但不会同步listOk上的添加/删除操作。因此,您的建议是:Collections.synchronizedList同步列表上的添加/删除操作+同步块同步迭代。我在这个问题上的主张是:ArrayList+锁定读取部分以同步迭代+锁定写入/删除部分。它似乎是等效的,不是吗?我不确定锁定读取部分将如何同步迭代。我提供的是列表同步问题的标准解决方案,它来自Collections.synchronizedList API。您需要同步迭代器和List2注释:1。为什么它比使用CopyOnWriteArrayList更好?2.如果对列表使用同步块,为什么不使用简单的ArrayList呢?如果我理解的很好,那么您的解决方案相当于使用CopyOnWriteArrayList和用于读取访问的补充锁,以确保具有最新版本的基础阵列。这就是为什么我认为使用带锁的ARARYLIST是足够的,因为我不需要添加同步。