Java 监听器的并发问题
Java Concurrency Issues concerning Listeners
关于 Java 的最佳或常见并发解决方案是什么?我在这个网站和其他网站上看到了很多解决方案,但是 none 解决了我的问题。
我的问题如下:我有一个vector
的一个class
是我自己写的。 (如果这有助于解决它,我可以很容易地把它变成 ArrayList
或类似的东西)
现在,我非常有规律地(每秒高达数千次)读取此 vector
中的所有元素并以某种方式操纵它们。同时,我根据 MouseListener
和 KeyListener
中的事件添加和删除元素(这对程序至关重要)。这当然给我带来了很多问题。我不想在添加或删除元素时读取 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
,因为任何更改都会在内部创建一个新数组,并且不会影响正在迭代的数组。它的设计初衷是为了容纳一个听众列表。
这样做的好处是迭代时不需要任何同步,并且锁定段非常短,迭代永远不会阻塞!
关于 Java 的最佳或常见并发解决方案是什么?我在这个网站和其他网站上看到了很多解决方案,但是 none 解决了我的问题。
我的问题如下:我有一个vector
的一个class
是我自己写的。 (如果这有助于解决它,我可以很容易地把它变成 ArrayList
或类似的东西)
现在,我非常有规律地(每秒高达数千次)读取此 vector
中的所有元素并以某种方式操纵它们。同时,我根据 MouseListener
和 KeyListener
中的事件添加和删除元素(这对程序至关重要)。这当然给我带来了很多问题。我不想在添加或删除元素时读取 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
,因为任何更改都会在内部创建一个新数组,并且不会影响正在迭代的数组。它的设计初衷是为了容纳一个听众列表。
这样做的好处是迭代时不需要任何同步,并且锁定段非常短,迭代永远不会阻塞!