2017-05-08 2 views
0

Ich habe einen Thread, der bei der Ausführung ein Message-Objekt erstellt, das in eine verknüpfte Liste in einem Monitor eingefügt wird. Zur gleichen Zeit warten zwei andere Threads darauf, dass diese Liste innerhalb kurzer Zeit ein Message-Objekt erhält (linkedlist.isEmpty()) canGetMessage.await(); Schleife, aber ich sende eine canGetMessage.signalAll(); Wenn Sie das Objekt in die Liste einfügen, werden die beiden anderen Threads nie aktiviert.Thread-Bedingung wacht nie auf

public void deliverMessage(Message m){ 
lock.lock(); 

try{ 
    linkedlist.add(m); 
    canGetMessage.signalAll(); 
}finally{ 
    lock.unlock(); 
} 
} 


public Message getMessage(){ 
lock.lock(); 

try{ 
while(linkedlist.isEmpty()){ 
    canGetMessage.await(); 
    } 
return linkedlist.remove(); //returns the item that has been in the list the longest 
} 
catch (InterruptedException e) { } //not required to handle these 

finally{ 
lock.unlock(); 
} 

Ich habe println, um zu sehen, wenn er aus der while-Schleife wird, aber dies nie passiert, und ich weiß nicht, warum ...

Edit: Nur um zu spezifizieren, die Sperre I‘ m Verwendung ist ein ReentrantLock

+2

Warum Sie nicht Verwenden Sie BlockingQueue mit Producer-Consumer-Muster? –

+1

Geben Sie ein vollständiges minimales Beispiel ein, das das Problem reproduziert. –

+0

Welche Typen sind 'lock',' linkedlist' und 'canGetMessage', wie werden sie erstellt? Und, ja, [MCVE] (http://stackoverflow.com/help/mcve) wäre sehr nützlich. – yeputons

Antwort

0

Guessing; Sie Probleme hier:

lock.lock(); 

Falls Sender/Empfänger das Objekt gleichen Sperre verwenden, kann dies nicht funktionieren. Empfänger erwerben das Schloss; und wird es nicht freigeben, bis der Absender der Liste einen neuen Eintrag hinzugefügt hat.

Aber der Absender kann nicht zu diesem Teil kommen; weil der Absender versucht, Sperre auf die bereits gesperrte Sperre. Die blockierte Sperre wird also blockiert.

Die "richtige" Antwort besteht darin, einen Sender/Empfänger mit einem BlockingQueue zu verbinden - anstatt etwas "wie eine Warteschlange" neu zu erfinden. Weitere Informationen zur Verwendung von BlockingQueue finden Sie unter here.

+1

Nein, canGetMessage.await() gibt die Sperre frei (vorausgesetzt, die Bedingung wurde mit dieser Sperre erstellt). –

+0

Wahrscheinlich ... mal sehen, was das OP sagt. Wenn es ihm nicht hilft, habe ich nichts dagegen, die Antwort zu löschen. – GhostCat

+2

@Telanore sollten Sie kein separates Schloss verwenden. Wenn Sie eine Erklärung wünschen, veröffentlichen Sie ein vollständiges minimales Beispiel, das das Problem reproduziert. Oder gehen Sie weiter und verwenden Sie eine BlockingQueue (die, ich stimme zu, ist sowieso eine bessere Lösung). –

0

Ich entschuldige mich bei allen, stellt sich die Frage bei der Schaffung der Fäden Layout selbst hatte ich versehentlich separate Monitore für jeden Thread, anstatt sie wurden so dass alle das gleiche mit ...

+1

Sie wollen entweder die Frage verbessern und sich selbst beantworten ... oder wahrscheinlich Ihre Frage dann löschen. – GhostCat