1

私は次のコードを書きましたが、どこかで間違っていると感じています。

public class ProcessQueue {

static BlockingQueue<String> queue = new LinkedBlockingQueue<String>();

public ProcessQueue() {
    process();
}

public void add(String message) throws InterruptedException {
    System.out.println("Added Queue size:" + queue.size());
    System.out.println("Locked by Producer");
    queue.put(message);
    System.out.println("Lock Released by Producer");
}

public static void process() {
    new Thread() {

        @Override
        public void run() {
            try {
                while (true) {
                    System.out.println("Locked by Consumer");
                    Message.send(queue.take());
                    System.out.println("Locked Released by Consumer");
                    System.out.println("Consuming Queue size:" + queue.size());
                }
            } catch (Exception ex) {
                System.out.print(ex.getMessage());
            }
        }
    }.start();
}
}

ここで、add(String)は文字列をキューに追加します。UDPポートから入力を受信するたびに呼び出されます。process()はキューを処理し、処理のためにメッセージクラスに送信します。出力されたロックおよび解放された印刷ステートメントが目的の順序ではありません。

編集

私の予想される答えは次のようになります。プロデューサーに追加された場合は、プロデューサーによってロックされます->キューに追加->リリースをロックします。同じように消費者にもなります。ただし、操作はインターリーブしないでください。つまり、プロデューサーによってロックされたものが印刷されると、コンシューマーによってロックされた状態で印刷されてからロックが解除されないようにする必要があります。

4

1 に答える 1

3

ここでブロッキングが発生するのは、キューが空のときだけです。それ以外の場合、プットは引き続き発生します。そのため、キューのサイズが1ずつ増えないことがわかります。LinkedBlockingQueueに境界を設定することをお勧めします。FyiLBQはデフォルトで無制限です

編集に基づいて編集します。

これまでの私の答えは、あなたが見ているものとその理由を説明することです。同期メッセージングパッシングキューを探しています。これは、次の方法で実行できます。

new SynchrnousQueue();
new LinkedBlockingQueue(1);
new ArrayBlockingQueue(1);
new TransferQueue();

SynchrnousQueueはまさにあなたが望むことをします。境界が1のLinked&ArrayBlockingQueueもほぼ同じです。TransferQueueは、Java 7で提供される新しいキューでありtransfer、スレッドが取得できるようになるまで待機するメソッドがあります。

于 2012-04-13T18:18:23.117 に答える