Java ConcurrentModificationException类的问题

时间:2016-04-07 20:56:54

标签: java multithreading swing jpanel

我基本上做了以下事情:
创建一个对象(例如武器对象),自动将该对象添加到所有这些类型的对象(ArrayList<Weapons>)的列表中。

JPanel使用更新程序线程每隔10秒绘制一次,该线程遍历ArrayList<Weapons>。我也在发送问题&#39;到另一台机器上的服务器,即询问是否允许该武器。如果不是,则客户端计算机修改武器对象。但是,每当我修改它时,我都会收到ConcurrentModificationException。而不是崩溃,我实际上希望它会在这一点上做,因为更改武器对象的方法是在不同的线程上,整个程序只是锁定。

我在这个程序中有超过1000行代码,并且有三个以上的线程运行访问列表,所以如果你需要任何代码,请问但是我现在不想发布,因为在我看来这个对线程专家来说似乎是一个微不足道的问题。

谢谢!

(将对象&gt;&gt;添加到对象列表&gt;&gt; JPanel&#34;更新程序&#34;线程每10个刻度不断绘制所有对象... 服务器说该对象不允许&gt;&gt;客户端计算机上的一个线程删除该对象(或切换一个表示它不可见的布尔值)&gt;&gt; ConcurrentModificationException的)。

2 个答案:

答案 0 :(得分:4)

引用Javadoc of ArrayList

  

请注意,此实施未同步。如果多个线程同时访问ArrayList实例,并且至少有一个线程在结构上修改了列表,则必须在外部进行同步。

您描述了访问列表的多个线程,并且至少有一个线程正在修改它。因此,对列表的所有访问必须在相互同步的块中完成。

e.g。迭代列表:

synchronized (list) {
  for (Weapons weapons : list) {
    // ...
  }
}

e.g。从列表中删除项目:

synchronized (list) {
  list.remove(0);
}

答案 1 :(得分:0)

我认为您可以使用同步版本的集合或列表,即java.util.Collections.synchronizedCollection(Collection<>)java.util.Collections.synchronizedList(List<>)。此外,如果迭代列表并删除项目,请确保使用启用从迭代器中删除项目的实现。一个好的候选人是java.util.ArrayList

其他技术是使用“监视器”,您可以声明类似于private static Object monitor = new Object();的属性,然后当代码尝试访问列表时,保护synchronized(monitor)块内的代码。使用此技术可确保在没有受保护的代码运行之前,没有其他线程可以修改您的列表。

请原谅我的英语:)。