2012-03-30 19 views
2

サーバーに割り当てられたクライアントのアドレスと名前を持つHas​​hMapがあります。ユーザーがサインオフすると、誰もが自分の出発についてのメッセージを受け取り、次にIを返します。 HashMapから彼を削除します。 。 問題は、私が使用しているメッセージを誰にでも送信するためにHashMapを反復するときです。 スレッドが発生し、結果として反復が発生する前にユーザーが削除されるため、メッセージは受信されません。 私はハッシュテーブル、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つのスレッド、つまりシーケンスでこれらの2つの操作を実行する必要があります。 – ControlAltDel

+0

適切な指標とexecture order sending-> deletionを確実にしてください。 – Howard

+1

'remove()'の前に 'start()'を呼び出すので、どのような順序で何が起こるかについては絶対に保証されません。 – biziclop

答えて

1

スレッドのようなサウンドは、メインスレッドではなくアドレスを削除する必要があります。これを行うには、HashMapをスレッドに渡す必要があります。

もう1つの方法は、アドレスを削除する前にスレッドが終了するまで待つことです。ただ、スレッドが実行されるまで待機するjoinを使用します。それはすべての並列性を殺すため、

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

は、この第二のアプローチは、しかし別のスレッドを持つことの目的に反していることに注意してください(メッセージは今一つずつ送信されます)。

関連する問題