Frage

Ich mag eine SynchronousQueue haben, wo ich Elemente aus einem Gewinde mit put() einzufügen, so dass der Eingang gesperrt ist, bis das Element in einem anderen Thread genommen wird.

Im anderen Thread ich viele Berechnungen durchführen und von Zeit zu Zeit überprüfen möchten, ob ein Element bereits vorhanden ist, und es verbrauchen. Aber es scheint, dass isEmpty() immer true zurück, auch wenn ein anderer Thread am put() Anruf wartet.

Wie auf der Erde ist das möglich? Hier ist der Beispielcode:

@Test
public void testQueue() throws InterruptedException {
    final BlockingQueue<Integer> queue = new SynchronousQueue<Integer>();

    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                if (!queue.isEmpty()) {
                    try {
                        queue.take();
                        System.out.println("taken!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // do useful computations here (busy wait)
            }
        }
    });
    t.start();

    queue.put(1234);
    // this point is never reached!
    System.out.println("hello");
}

EDIT: Weder isEmpty () noch peek () arbeiten, hat man Umfrage () zu verwenden. Dank!

War es hilfreich?

Lösung

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/SynchronousQueue.html#put(E) :

isEmpty
public boolean isEmpty ()
Immer wieder wahr. Ein SynchronousQueue hat keine interne Kapazität.

(nicht in diesen im Detail aussah, aber Sie könnten einen Blick nehmen wollen entweder Umfrage oder nehmen statt)

Andere Tipps

Neben Tim Antwort - Sie nichts im Consumer-Thread tun, sondern kontinuierlich isEmpty () in einer engen Schleife aufrufen. Anstatt das O nicht gefragt, es zu laufen, bis es ist etwas nützlich für sie tun, ist der Verbraucher Faden kontinuierlich beschäftigt. Auch wenn isEmpty richtig funktioniert, würde der Produzent Thread bekommt selten eine Chance zu laufen.

Sie könnten (wenn isEmpty () Arbeit haben, oder Sie geschaltet poll () zu verwenden), um die Verbraucher Schlaf ein wenig zwischen den Tests, wenn die Warteschlange leer ist der Hersteller eine Chance zu geben zu laufen, oder (vorzugsweise) nur nehmen Sie die isEmpty (Test) und lassen Sie den Thread-Block auf der Mutex innerhalb des Take () in einer vernünftigen Art und Weise statt Polling.

Ihr Code sieht aus wie Sie eine Umfrage zu tun versuchen. warum nicht einfach rufen Sie die Umfrage () Methode?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top