我已经设置了具有connection
方法的send
对象(我无法更改的库代码)。如果发送失败,他们将回调我实现的通用onClosed
侦听器,该侦听器在我的代码中调用removeConnection()
,这将从集合中删除连接。onClosed
回调是通用的,可以随时调用。例如,在对等方关闭连接时调用,而不仅仅是在写入失败时调用。
但是,如果我有一些循环遍历我的连接并发送的代码,则onClosed
回调将尝试在迭代过程中修改集合。
我当前的代码在每次迭代之前创建连接列表的副本。但是,在剖析中这已显示非常昂贵。
Set<Connection> connections = new ....;
public void addConnection(Connection conn) {
connections.add(conn);
conn.addClosedListener(this);
}
@Override void onClosed(Connection conn) {
connections.remove(conn);
}
void send(Message msg) {
// how to make this so that the onClosed callback can be safely invoked, and efficient?
for(Connection conn: connections)
conn.send(msg);
}
在迭代过程中如何有效地修改集合?
最佳答案
ConcurrentSkipListSet可能是您想要的。
您也可以使用CopyOnWriteArraySet。当然,这仍然会产生副本,但是,只有在修改集后才会这样做。因此,只要不定期添加或删除Connection
对象,这将更加有效。