2016-04-20 21 views
2

ここでStackOverflowに関する最初の質問があるので、間違って質問してください。Java:2つの異なる入力ソースを使用したマルチスレッドと反応

基本的には、ユーザーがコンソールに「quit」と入力するまで、無期限にマルチキャストアドレスを待ち受けるマルチキャストクライアントを作成しています。私は、MulticastSocketのSO_TIMEOUTを設定し、 "quit"がタイプされているかどうかをチェックし、受信メソッド呼び出しに戻るのが実際には機能しないことを発見しました。これは、タイムアウトとコンソールブロックのチェックの直後。だから、私は最良の選択肢は、2つのスレッドがソケットを待ち受け、何かを受信するまでブロックし、もう1つのスレッドが終了するように指示されるまでコンソールをリッスンすることだと考えています。私が持っている唯一の問題は、ソケットを閉じて終了させるためにソケットリスンスレッドにソケットスレッドを伝えることについてどうやって行くのかが分かりません。 System.end()は動作しますが、私はソケットを開いたままにしておくことを恐れています。

TLDR;クラスのmainメソッドがスレッドを開始し、そのスレッドが終了すると特定の方法で応答する方法はありますか?あるスレッドではコンソールを聴いて、別のスレッドではMulticastSocketを、クライアントクラスのメインでは聴く必要があります。

ありがとうございました。

答えて

1

私はSocket.close()と呼んでソケットを閉じます。これにより、そのスレッドでIOExceptionが生成されます。したがって、これを行う前に、closed = true;のようなフラグを設定し、エラーを出力する前に他のスレッドがこれをチェックするようにします。つまり、クローズされている場合はIOExceptionを出力しません。このようなもの。

public class SocketListener implements Runnable, Closeable { 
    final MulticastSocket socket; 
    final Consumer<DatagramPacket> packetConsumer; 
    volatile boolean closed; 

    public SocketListener(MulticastSocket socket, Consumer<DatagramPacket> packetConsumer) { 
     this.socket = socket; 
     this.packetConsumer = packetConsumer; 
    } 

    @Override 
    public void run() { 
     DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); 
     try { 
      while(!closed) { 
       socket.receive(packet); 
       packetConsumer.accept(packet); 
      } 
     } catch (IOException e) { 
      if (!closed) 
       e.printStackTrace(); 
     } 
    } 

    @Override 
    public void close() throws IOException { 
     closed = true; 
     socket.close(); 
    } 
} 

例えば、あなたのメインスレッドでは、あなたはここで少し混乱し

MulticastSocket socket = ... 
Consumer<DatagramPacket> packetConsumer = ... 
try (SocketListener listener = new SocketListener(socket, packetConsumer)) { 
    boolean finished = false; 
    do { 
     // read from the console 
     if (some condition) 
      finished = true; 
    } while(!finished); 
} // calls close() for you. 
+0

行うことができます。コンソールから読み込んだスレッドは、ソケットリスナのクローズとどのように対話しますか?私自身のコードでは、クライアントがRunnableインターフェイスを実装していると思いますが、2つのスレッドがどのようにやりとりするかについて少し不明です。私の質問が日常的なように見える場合、私はあまりにも多くのことを謝っています。 – user16728

+0

@ user16728あなたは 'close()'メソッドを呼び出すコンソール読書スレッドを持っています。 –

+0

@ user16728答えに例を追加しました。 –

関連する問題