3

タスクは、スレッドセーフな独自のメッセージキューを実装することです。

私のアプローチ:

public class MessageQueue {
    /**
     * Number of strings (messages) that can be stored in the queue.
     */
    private int capacity;

    /**
     * The queue itself, all incoming messages are stored in here.
     */
    private Vector<String> queue = new Vector<String>(capacity);

    /**
     * Constructor, initializes the queue.
     * 
     * @param capacity The number of messages allowed in the queue.
     */
    public MessageQueue(int capacity) {
        this.capacity = capacity;
    }

    /**
     * Adds a new message to the queue. If the queue is full,
     * it waits until a message is released. 
     *
     * @param message
     */
    public synchronized void send(String message) {
        //TODO check
    }

    /**
     * Receives a new message and removes it from the queue. 
     *
     * @return
     */
    public synchronized String receive() {
        //TODO check
        return "0";
    }
}

キューが空でremove()を呼び出す場合は、別のスレッドがsend()メソッドを使用できるようにwait()を呼び出します。それぞれ、反復のたびにnotifyAll()を呼び出す必要があります。

質問:それは可能ですか?つまり、オブジェクトの1つのメソッドでwait()と言うと、同じオブジェクトの別のメソッドを実行できるということですか?

そして別の質問:それは賢いようですか?

4

1 に答える 1

7

質問:それは可能ですか?つまり、オブジェクトの1つのメソッドでwait()と言うと、同じオブジェクトの別のメソッドを実行できるということですか?

はい!これがまさにwaitとnotify/notifyAllの設計方法です。オブジェクトでwait()を呼び出すと、そのスレッドは、別のスレッドが同じオブジェクトでnotify/notifyAllを呼び出すまでブロックされます。

そして別の質問:それは賢いようですか?

はい!これはまさに、低レベルのJava操作を使用してメッセージキューを実装する(そして実装した)方法です。


興味があれば、これを正確に実行するBlockingQueueクラスが標準ライブラリにあります。このようなクラスを使用するだけの場合は、BlockingQueueを使用してください。ただし、メッセージキューの実装方法を学習することが目標である場合は、アプローチを続行してください。これはまさに正しいことです。

public interface BlockingQueue<E>
extends Queue<E>

要素を取得するときにキューが空でなくなるのを待ち、要素を格納するときにキューでスペースが使用可能になるのを待つ操作を追加でサポートするキュー。

于 2012-12-02T17:03:19.677 に答える