Java HashSet迭代器删除从不适用于套接字/线程类

Java HashSet迭代器删除从不适用于套接字/线程类,java,Java,我正在开发一个基本的客户机/服务器java应用程序。一切正常,只是删除死连接的my代码实际上从未删除它们 当侦听器线程遇到异常断开管道等情况时,它会设置一个布尔值,表示它已死亡,以便下次服务器线程运行时,它会扫描所有标记为已死亡的连接,并应将其删除,以便我们不再尝试写入它们 下面的代码正在运行,我看到了日志消息-但是.remove从未执行任何操作。当我在此代码块之前和之后调试pool.size时,它从不减少-只在建立新连接时增加 public static volatile HashSet<

我正在开发一个基本的客户机/服务器java应用程序。一切正常,只是删除死连接的my代码实际上从未删除它们

当侦听器线程遇到异常断开管道等情况时,它会设置一个布尔值,表示它已死亡,以便下次服务器线程运行时,它会扫描所有标记为已死亡的连接,并应将其删除,以便我们不再尝试写入它们

下面的代码正在运行,我看到了日志消息-但是.remove从未执行任何操作。当我在此代码块之前和之后调试pool.size时,它从不减少-只在建立新连接时增加

public static volatile HashSet<ClientListener> pool = new HashSet<ClientListener>(); 

Iterator<ClientListener> listeners = pool.iterator();
while( listeners.hasNext() ){
    ClientListener l = listeners.next();
    if( l.isDead() ){
        MyApp.log( "Removing dead/errored client listener..." + l.getIdentifier() + " " + l.listenerId );
        listeners.remove();
    }
}

正如所写的,代码看起来还可以。但是,您将池声明为volatile意味着代码是多线程的,如果另一个线程正在向池中添加新的ClientListener对象,则此代码不是线程安全的。这可能足以导致异常现象,从而解释这种奇怪的行为

一个简单的解决办法就是改变

   HashSet<ClientListener> 

您可以/应该做的另一件事是比较pool.size在listener.remove调用前后所说的内容

最后,listener.remove调用可能引发异常。如果您在调用堆栈中进一步挤压该异常,那么这可能解释了为什么您无法了解这里发生了什么

   ConcurrentHashMap<ClientListener, ClientListener>