2009-03-04 6 views
5

Jetzt bin ich mir nicht sicher, ob das eine dumme Frage ist, bitte ertragen Sie mit mir, wenn es ist.Java: Was ist, wenn überhaupt, durch synchronisierte Methoden gesperrt, abgesehen von dem Objekt, zu dem sie gehören?

Ist die Sperre für ein Objekt "rekursiv", d. e. Wenn zwei Objekte Referenzen auf ein drittes Objekt in ihren Feldern haben und ein Thread eine synchronisierte Methode auf einer der beiden ausführt, kann ein anderer Thread auf das dritte Objekt zugreifen?

// a and b are some objects that implement Runnable 
// they both reference the same third object 
a.ref = c; 
b.ref = c; 

// a is run in a thread and processes some data in a loop for a long time 
// the method the loop belongs to is declared synchronized 
threadA = new Thread(a); 
threadA.start(); 

a.someSyncedMethod(); // this would block ... 
b.ref.someOtherSyncedMethod(); // ... but would this? 
a.ref.someOtherSyncedMethod(); // ... and how about this? 
+0

Es ist überhaupt keine blöde Frage - nur eine einfache Frage. Kein Problem, um ein besseres Verständnis der Sprachgrundlagen zu bekommen –

+0

Danke. Ich dachte, das sollte irgendwie offensichtlich sein, aber ich habe es immer noch nicht verstanden. –

Antwort

10

Es lohnt sich, die Konzepte von "a lock" und "locking a object" zu trennen. Es gibt keine wirkliche Vorstellung davon, ein Objekt zu "verriegeln" - es gibt "Erfassen (und Freigeben)" des mit verbundenen Schlosses eines Objekts. Ja, es klingt, als ob ich pingelig bin - aber die Unterscheidung ist wichtig, denn wenn man über ein Objekt spricht, das gesperrt ist, klingt es so, als ob keine anderen Threads irgendetwas im Objekt ändern können, während diese Sperre gehalten wird.

Stattdessen bedeutet es nur, dass kein anderer Thread in der Lage ist, das gleiche Schloss zu erhalten, während das Schloss gehalten wird. Es gibt keine direkte Beziehung zwischen der Sperre und einem beliebigen Inhalt des Objekts, mit dem die Sperre verknüpft ist.

Methoden, die als "synchronisiert" deklariert sind, erfassen die Sperre, die der Instanz des Objekts zugeordnet ist, zu dem sie gehören. Dies bewirkt nur, dass andere synchronisierte Methoden auf dasselbe Objekt warten und synchronisierte Anweisungen, die explizit darauf synchronisiert werden.

Persönlich mag ich keine synchronisierten Methoden - ich mache es gerne klarer, indem ich explizit eine (private, letzte) Mitgliedsvariable synchronisiere, die nur für die Synchronisation verwendet wird.

+0

Ja, es hilft, aber ich bin mir nicht sicher, ob ich es wirklich verstanden habe. Ist es richtig, dass nur solche Anrufe blockieren, die dieselbe Sperre benötigen, d. e. ruft synchronisierte Methoden derselben Instanz auf, während jeder Code, der ein Mitglied von a sperrt, fortfährt? –

+0

Ja. Persönlich mag ich keine synchronisierten Methoden - ich mache es gerne klarer, indem ich explizit eine (private, letzte) Mitgliedsvariable synchronisiere, die nur für die Synchronisation verwendet wird. –

+0

Ich habe das oben in Ihrem Post bearbeitet, ich hoffe, ich habe es richtig gemacht. Vielen Dank! –

1
a.someSyncedMethod(); // this would block ... 

Nur wenn Sie entweder die run-Methode mit synchronisierten oder haben ThreadA Laufcode in synchronisierten Methoden markieren.

In der JVM besitzt jedes Objekt einen so genannten Monitor. Nur ein Thread kann den Monitor besitzen, der jeweils einem bestimmten Objekt zugeordnet ist. Synchronisiert ist das Mittel, mit dem Sie dem aktuellen Thread sagen, dass er den Monitor holen soll, bevor er fortfährt.

Auch die Klasse selbst besitzt einen Monitor für statische Methoden.

0

Die Bedeutung eines "Lock" (eigentlich ist diese Variante ein Monitor) ist eine Konvention, keine Zugriffsbeschränkungen werden erzwungen.

Die Funktionsweise beruht darauf, dass alle Objekte sich gut verhalten und vor dem Zugriff auf die Daten die entsprechende Sperre erhalten. Nur durch Kapselung dieses gewünschten Verhaltens innerhalb einer Klasse mit geeigneten Zugriffskontrollen können Sie es für die Client-Objekte erzwingen.

Verwandte Themen