Synchronisieren auf BlockedQueue
-
21-09-2019 - |
Frage
ich einen Code Stück haben, dass ich bin der Überprüfung (mit FindBugs ).
public class MyClass{
...
private BlockedQueue q = new LinkedBlockingQueue<MyData>(1000);
private static final batchSize = 1000;
public boolean testMethod(){
boolean done = false;
synchronized(q){
if(q.size == batchSize){
q.notify();
done = true;
}
}
return done;
}
Wenn ich FindBugs auf diesem Stück Code ausführen, es beschwert sich, dass -
Dieses Verfahren führt Synchronisation ein Objekt, das eine Instanz einer ist Klasse aus dem java.util.concurrent Paket (oder deren Subklassen). Instanzen diese Klassen haben eine eigene Concurrency Kontrollmechanismen, die eigenständig und unvereinbar mit der Verwendung des Schlüsselworts synchronisiert.
Wenn ich den synchronisierten Code Stück synchronized(q){
Kommentar aus, es klagt -
Diese Methode ruft Object.notify () oder offensichtlich Object.notifyAll () ohne eine Sperre für das Objekt zu halten. Berufung notify () oder notifyAll () ohne ein Schloss führt in einem gehalten IllegalMonitorStateException Wesen geworfen
Wie würde ich diese Methode implementieren, so dass es FindBugs Validierung passiert? Ist die obige Implementierung richtige für Benachrichtigung in den Fällen, für die gleichzeitige Klassen?
Danke.
Lösung
notify()
geht zusammen mit wait()
und soll nicht mit Klassen von java.util.concurrent
verwendet werden.
verwendet Blocking interne Mechanismen auf einem put()
zu blockieren, wenn es keinen Platz für mehr Elemente oder auf poll()
ist, wenn kein Element zu konsumieren. Sie haben nicht zu diesem kümmern.
Andere Tipps
Der erste Fehler ist, die besagt, dass Sie nicht primitive Synchronisation Kontrollen auf java.util.concurrent Klassen (wie Blocking) verwendet werden sollen.
Im Allgemeinen ist dies eine gute Praxis, wie sie von der Synchronisation für Sie kümmern. Ich könnte mir vorstellen, dass es einen besseren Weg, um Ihr Problem bei der Hand zu lösen. Was ist das eigentliche Problem Sie versuchen zu lösen?
Der zweite Fehler verursacht durch die Tatsache, dass Sie die Sperre / Monitor eines Objekts besitzen muss (durch sychronizing darauf) Warten auf Anruf / benachrichtigen / notifyAll drauf
Blocking ist ein syncronizer Objekt - Koordinaten der Steuerfluss von Threads basierend auf seinen Zustand und damit die Kontrolle Fluss Erzeuger / Verbraucher-Threads, weil nehmen und put Block, bis die Warteschlange des gewünschten Zustand (nicht leer oder nicht voll) eintritt.
Auch gute Praxis in Gleichzeitigkeit Programmierung geht davon aus, dass die Wartezeit und notify in while-Schleife platziert.