Update: Klicken Sie unten auf diese Frage, um eine vollständige Antwort zu erhalten.
Ich möchte einen sekundären Thread ausführen, so dass mein Haupt-Thread und mein sekundärer Thread Operationen abwechselnd ausführen (nein, ich möchte nicht alle Operationen im Haupt-Thread ausführen, es ist für einen Komponententest).
Ich kam zu zwei verschiedenen Lösungen, ich weiß nicht, welche die beste ist, und ich habe Fragen bezüglich der ersten:
Ich kam zu etwas mit einem Exchanger ( während ich nicht nur ein Objekt austauschen möchte).
%Vor%exchange
-Methode die Speichersynchronisierung genauso ausführt wie die Verwendung von Lock
? Eine andere Lösung, die eine Bedingung verwendet:
%Vor%Es scheint mir ein bisschen komplizierter.
Was halten Sie für die beste Lösung? Tue ich es richtig, oder vermisse ich eine andere offensichtliche Lösung?
Ich habe kein CountDownLatch
verwendet, da ich abwechselnd mehrere -Operationen ausführen möchte, und das CountDownLatch
kann nicht zurückgesetzt werden. Und ich fand nicht, dass CyclicBarrier
den Code einfacher machte ... (eigentlich habe ich nicht ganz verstanden, wie man es benutzt, aber es sah nicht einfacher aus als mit Exchanger
oder Condition
)
Danke.
@ Clément MATHIEU hat in seinen Kommentaren zu seiner akzeptierten Antwort verschiedene Beispiele dafür angegeben, wie dies zu erreichen ist, siehe: Ссылка
Es gibt drei Beispiele, eines mit CyclicBarrier
, ein anderes mit Exchanger
und ein letztes mit 2 Semaphore
s. Während er zu Recht sagt, dass das "ausdrucksstärkere ist das Semaphor-basierte", wählte ich ein Exchanger
zur Vereinfachung. Mein Komponententest wurde:
Bin ich richtig, dass die Austauschmethode eine Speichersynchronisation durchführt, genauso wie die Verwendung einer Sperre?
Sie haben Recht. Das Javadoc gibt an, dass es eine Vor-Vor-Beziehung gibt:
" Speicherkonsistenzeffekte: Für jedes Paar von Threads, die Objekte über einen Exchanger erfolgreich austauschen, passieren Aktionen vor dem Austausch () in jedem Thread - vor denen nach einer Rückkehr von der entsprechenden exchange () in der anderer Thread. "
Was halten Sie für die beste Lösung?
Beide sind gleichwertig. Sie sollten die Ausdruckskraft zielen. Ich finde die Synchronisation / Lock / Monitor basierte Lösung expressiver als die auf Exchange basierende Lösung. Aber es ist nicht wirklich wichtig, wenn Sie diesen Code in einer dedizierten Klasse abstrahieren.
Tue ich es richtig, oder vermisse ich eine andere offensichtliche Lösung?
AFAIK nein Wenn Sie das Rad nicht neu implementieren wollen.
Bitte beachten Sie, dass Ihre ReentrantLock-basierte Lösung auch mit einer einfachen alten Synchronisation oder einem Monitor von Guava geschrieben werden kann.
Siehe: Ссылка für einen Vergleich.
Und ich habe nicht gefunden, dass der CyclicBarrier den Code einfacher macht ... (eigentlich habe ich nicht ganz verstanden, wie man ihn benutzt, aber er sieht nicht einfacher aus als
CyclicBarrier passt nicht zu Ihren Anforderungen. Es ist nicht für den gegenseitigen Ausschluss ausgelegt; Es ermöglicht einer Gruppe von Threads, eine gemeinsame Barriere zu definieren. Threads werden gleichzeitig ausgeführt und warten auf einander, bevor sie zum nächsten Schritt übergehen.
Tags und Links java concurrency