这个问题是在描述(和解决)问题的一个比较特殊的情况下这个问题。
我有两个方法,stopAndRemove(ServerObjectserver)和close()方法。后者应关闭所有服务器并将其从服务器列表中删除。该列表定义为
List<ServerObject> server.
我不想在closeCurrentlyOpen中从stopAndRemove获得几乎相同的代码,所以我想执行以下操作:
public void closeCurrentlyOpen() { for(ServerObject server : this.servers) { stopAndRemove(server) } }
这将不起作用,因为这将导致ConcurrentModificationException。我试图复制一份清单
List<ServerObject> copyList = new ArrayList<ServerObject>(this.servers);
并将其用作foreach循环的列表。但是,当我遍历copyList时,另一个线程可能会将Server添加到服务器列表中,但是closeCurrentlyOpen应该会导致一个空列表。由于addServerToList方法已同步到服务器列表,因此请执行此操作
public void closeCurrentlyOpen() { synchronized(this.servers) { for(ServerObject server : this.servers) { stopAndRemove(server) } } }
将通过修改解决问题。但是,然后我无法同步stopAndRemove方法中的代码,如果直接调用它,则是必须的。
在我看来,这三种方法的设计可能需要修整。有想法吗?
从stopAndRemove()中分离出一个方法stop()。然后使用显式迭代器编写循环,执行停止操作,然后执行iterator.remove()。
方法名称中的“和”是代码气味。