0

カスケード方式で 2 つのスレッドに渡される 2 つのキューの同期を処理しようとしています。したがって、クライアントからの接続をリッスンする ServerThread と、サーバー スレッドによってクライアントからの接続が受け入れられた場合に作成される ConnectedThread の 2 つのスレッドがあります。これらのキューのパスを ConnectedThread クラスのスレッド コンストラクターに同期する方法がわかりません。これらのキューを同期する必要がありますか? そして、何がベストプラクティスなのかわかりません。私はこれをやろうとしました:

synchronized (this) {
    new ConnectedThread(socket, inQueue, outQueue).start();
}

とによって:

synchronized (inQueue) {
    synchronized (outQueue) {
        new ConnectedThread(socket, inQueue, outQueue).start();
    }
}

すべてはもちろん"run()"ServerThread クラスのスレッドのメソッドにあります。

コード内のすべては次のようになります。

private class ServerThread extends Thread {
    public ServerThread(int port, Queue<ThreadMessage> in,
            Queue<ThreadMessage> out) throws Exception {
        // TODO Auto-generated constructor stub

        setName("ServerThread");

        try {
             server = new ServerSocket(port);

             synchronized (in) {
                 synchronized (out) {
                     inQueue = in;   outQueue = out;
                 }
             }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            throw new Exception();
        }
   }

   private ServerSocket server;

   private Queue<ThreadMessage> inQueue, outQueue;

   private boolean running = true;

   @Override
   public void run() {
       // TODO Auto-generated method stub
       while (running) {
           try {
               Socket socket = server.accept();

               synchronized (inQueue) {
                   synchronized (outQueue) {

                       try {
                           new ConnectedThread(socket, inQueue, outQueue)
                           .start();
                       } catch (Exception e) {
                           // TODO Auto-generated catch block
                           e.printStackTrace();
                       }

                   }
               }

           } catch (IOException e) {
           // TODO Auto-generated catch block
               e.printStackTrace();
           }
       }
   }
}

SeverThread クラスのスレッドは、synchronized メソッド内に作成されます。

public synchronized void startServer(int port, Queue<ThreadMessage> in, 
        Queue<ThreadMessage> out) throws Exception {

    serverThread = new ServerThread(port, in, out);
    serverThread.start();
}

適切な方法でそれに対処する方法はありますか?

少し早いですがお礼を。

PS私の英語でごめんなさい。PSキューはのインスタンスですLinkedList

4

3 に答える 3

1

Queueクラス メンバーへのインスタンスの参照の割り当てを同期する必要はありません。

poll()同期する必要があるのは、やなどのキューで実行する操作ですoffer()

同期は何に適していますか? さて、ConnectedThread共有オブジェクト(あなたの例ではインキューとアウトキュー)で動作する複数のスレッド(あなたの例では)がある場合、アプリケーションがスレッドセーフな方法で操作を実行するために操作を同期する必要があります。

例: 2 つのスレッドがキューから読み取りたい場合、キューが空ではない (キューに 1 つの要素が含まれている) ことを両方のスレッドが認識した場合、両方がpollそれを呼び出しますが、1 つのスレッドだけがキューから要素を取得します。他のスレッドが取得nullされ、ロジックで問題が発生します。そのため、キューの読み取り操作と書き込み操作を同期する必要があります。

于 2013-06-18T13:17:44.913 に答える
0

同期は、オブジェクトにアクセスする場合 (たとえば、キュ​​ーを参照または変更する場合) にのみ有効であり、参照 (つまり、代入または引数の受け渡し) には有効ではありません。

投稿されたコードには、キューの処理方法が記載されていません。

于 2013-06-18T13:18:42.600 に答える