2012-03-30 41 views
2

我有一个HashMap,其中包含在服务器上分配的客户端的地址和名称。当用户注销时,每个人都收到有关他离开的消息,然后我将其从HashMap 。 问题是,当我迭代HashMap以便向所有人发送消息时,我使用 一个线程,结果在迭代发生之前删除用户,因此他没有收到消息。 我试过Hashtable,ConcurrentHashMap是徒劳的。 当我跳过去除线然后它的作品。 如何避免它,我可以使用不同类型的地图;迭代期间从HashMap中删除的值

private HashMap<InetAddress, String> users = new HashMap<InetAddress, String>(); 

。 。 。

UDPServerSender sender = new UDPServerSender(str, address, true); 
         sender.start(); 
         users.remove(address); 

。 。 。

public class UDPServerSender extends Thread { 

    @Override 
    public void run() { 
      iterator = users.keySet().iterator(); 
      while (iterator.hasNext()) { 
       InetAddress inetaddress = (InetAddress) iterator.next(); 

我想我可以发送一个单独的消息给签约用户。

+0

简单的答案是,为了保证用户在迭代时不在表中,您需要在1个线程中执行这两个操作,即按顺序 – ControlAltDel 2012-03-30 15:07:43

+0

您应该通过适当的度量同步线程,并且确保发送命令发送 - >删除。 – Howard 2012-03-30 15:09:01

+1

由于您在remove()之前调用'start()',因此完全不能保证以什么顺序发生。 – biziclop 2012-03-30 15:09:50

回答

1

声音像线程应该删除地址,而不是主线程。为此,您需要将HashMap传递给该线程。

另一种替代方法是在删除地址之前等待线程完成。只需使用join等到线程完成:

UDPServerSender sender = new UDPServerSender(str, address, true); 
         sender.start(); 
         sender.join(); 
         users.remove(address); 

注意,这第二种方法失败,虽然有一个单独的线程的目的,因为它杀死所有的并行机制(邮件现已发送一个接一个)。