有关监听器的Java并发问题

时间:2015-02-01 19:57:05

标签: java vector concurrency concurrentmodification

Java的并发性最佳或常见解决方案是什么?我在这个网站和其他网站上看到了很多解决方案,但没有一个能解决我的问题。

我的问题如下:我自己写了vector class。 (如果这有助于解决它,我可以很容易地使它成为ArrayList或类似的东西) 现在,我定期(每秒数千次)阅读这个vector中的所有元素并以某种方式操纵它们。同时,我根据我的MouseListener和我的KeyListener(这对程序至关重要)中的事件添加和删除元素。这当然给了我很多问题。在添加或删除元素时,我不想阅读vector,因为这会抛出java.util.ConcurrentModificationException。但是,我无法真正使用临时vector来存储这些事件,因为这会在向其添加内容时产生清除此vector的问题。你怎么摆脱这个烂摊子?

2 个答案:

答案 0 :(得分:3)

您可以使用java.util.Collections使用线程安全包装器包装Vector项。 List有一种特定的方法,即synchronizedList,但不适用于Vector。这只通过同步所有公共方法调用,add()和remove()等来解决部分问题。

private Collection<Thing> things =
         Collections.synchronizedCollection(new Vector<Thing>());

(或列表)

private Collection<Thing> listeners =
       Collections.synchronizedList(new ArrayList<Thing>());

你还需要保护你的迭代......有两种方法可以做到这一点,你可以在迭代时锁定集合......

synchronized (things) {
    for (Thing thing : things) {

    }
}

或复制一遍并重复...

for (Thing thing : things.toArray(new MouseListener[]{})) {

}

答案 1 :(得分:1)

您想使用CopyOnWriteArrayList。这在多线程和并发编程环境中使用是安全的。

当迭代CopyOnWriteArrayList时,您将无法获得ConcurrentModificationException,因为任何更改都会在内部创建一个新数组,并且不会影响正在迭代的数组。它主要用于托管一组听众。

这样做的好处是在迭代时不需要任何同步,并且锁定段非常短,迭代永远不会阻塞!