2013-06-04 13 views
18

Während Gleichzeitigkeit in Java zu lesen, ich habe folgende Zweifel:Synchronisierte Vs Semaphore

  1. Does Java bietet untere Ebene Konstrukt dann zur Synchronisation synchronisiert?

  2. Unter welchen Umständen werden wir verwenden Semaphore über synchronisiert (welcher Monitor Verhalten in Java bietet)

+0

ich denke, für Frage 1, können wir ReentrantLock und Condition-Objekte ,, sie sind eine Art von Konstrukten der unteren Ebene. – Addict

Antwort

34

Synchronized erlaubt nur ein Thread der Ausführung der Ressource zur gleichen Zeit zuzugreifen. Semaphore erlaubt bis zu n (Sie können wählen n) Threads der Ausführung, um auf die Ressource zur gleichen Zeit zugreifen.

8
  1. Es gibt auch volatile Schlüsselwort nach http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.htmlvolatile Variablenzugriff ist effizienter als diese Variablen durch synchronisierte Code Zugriff

  2. java.util.concurrent.Semaphore verwendet wird, um die Anzahl der Fäden zu beschränken, die eine Ressource zugreifen kann. Das heißt, während synchronized nur einem Thread erlaubt, die Sperre zu übernehmen und die synchronisierte Block/Methode auszuführen, erlaubt Semaphore die Erlaubnis bis zu n Threads zu gehen und blockiert die anderen.

+0

synchronisiert bietet Lösung für Thread-Interferenz- und Speicherkonsistenzfehler, jedoch flüchtig, bietet nur Lösung für Speicherkonsistenzfehler, so dass wir nicht volatile verwenden können, um Atomizität in Operationen bereitzustellen, fehle ich hier etwas? – Addict

+0

volatile bietet auch atomaren Zugriff auf long/double –

+0

Mit volatile Sie möglicherweise noch schmutzige Lesevorgänge und korrumpieren Sie Ihre gemeinsamen Werte. Es ist also keine Alternative für synchronisiert. –

2

Es gibt auch atomics. Dies ermöglicht den Zugriff auf den grundlegenden Hardware-Befehl "compare-and-swap", der die Grundlage für die gesamte Synchronisierung ist. So können Sie beispielsweise eine Nummer sicher erhöhen. Wenn Sie ein flüchtiges Feld ++ ein anderes Thread, das dieselbe Anweisung ausführt, könnte das Feld lesen, bevor Ihr Thread schreibt, dann schreiben Sie zurück nach Ihr Thread. Also ein Inkrement geht verloren. Atomics lesen und schreiben "atomisch" und vermeiden so das Problem.

Eigentlich flüchtige Bestandteile, Synchronized Aussagen, und atomics neigen alle Thread-Daten zu zwingen, aus dem Hauptspeicher und/oder geschrieben in dem Hauptspeicher entsprechend aufgefrischt werden, so dass keiner von ihnen sind tatsächlich dass niedrige Pegel. (Ich vereinfache hier. Im Gegensatz zu C#, Java hat nicht wirklich ein Konzept von "Hauptspeicher".)