Java 监听器的并发问题

Java Concurrency Issues concerning Listeners

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

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

您可以使用 java.util.Collections 使用线程安全包装器包装您的项目向量。 List 有一个特定的方法,即 synchronizedList 但 Vector 没有。这仅通过同步所有 public 方法调用、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[]{})) {

}

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

迭代 CopyOnWriteArrayList 时,您不会得到 ConcurrentModificationException,因为任何更改都会在内部创建一个新数组,并且不会影响正在迭代的数组。它的设计初衷是为了容纳一个听众列表。

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