2012-04-19 3 views
6

Nach meinem Verständnis, sollte das folgende Stück Code zu einem Deadlock führen. Der Grund dafür ist, dass, wenn der Thread t1 das statische Objekt firstData sperrt, er eine Sperre für die Klasse erhalten hat. Wenn er also versucht, ein anderes statisches Objekt secondData zu sperren, sollte die Anforderung blockieren.Locking statische Mitglieder einer Klasse

jedoch läuft das Programm fein und druckt *** Successfully acquired both the locks

Was ist das statische Objekte zu Sperren, die fehlen im hier?

public class Deadlock { 
    public static void main(String[] args) { 

     Thread t1 = new Thread(new DeadlockRunnable()); 
     t1.start(); 
    } 
} 

class DeadlockRunnable implements Runnable { 
    static Object firstData = new Object(); 
    static Object secondData = new Object(); 

    public void run() { 
     synchronized(firstData) { 
      synchronized(secondData) { 
       System.out.println("*** Successfully acquired both the locks"); 
      } 
     } 
    } 

} 

Für alle, die antworteten, dass die Sperren Objekt sind, statt Klasse, nehmen Sie bitte einen Blick auf this

Antwort

14

Erstens haben Sie hier einen Fehler:

Der Grund dafür ist Wenn der Thread t1 das statische Objekt firstData sperrt, hat er eine Sperre für die Klasse erhalten.

Durch das Sperren eines statischen Objekts wird nur dieses Objekt und nicht die Klasse gesperrt. Sie sperren zwei separate Objekte.

Die question you refered to ist etwa synchronized methods nicht synchronized statements. Diese beiden verwandten Konstrukte arbeiten auf leicht unterschiedliche Weise.


Zweitens, auch wenn Sie auf demselben Objekt wurden blockiert, Ihr Code würde Deadlock noch nicht (ideone). Intrinsische Sperren sind Wiedereintritt. Das bedeutet, dass sich ein Thread nicht selbst blockiert, wenn er zweimal versucht, die gleiche Sperre zu übernehmen.

Reentrante Synchronisation

Daran erinnern, dass ein Thread eine Sperre nicht erwerben kann, von einem anderen Thread gehört. Ein Thread kann jedoch eine Sperre erlangen, die er bereits besitzt. Wenn einem Thread ermöglicht wird, dieselbe Sperre mehr als einmal zu aktivieren, wird die Reentry-Synchronisierung aktiviert. Dies beschreibt eine Situation, in der synchronisierter Code direkt oder indirekt eine Methode aufruft, die auch synchronisierten Code enthält, und beide Codesätze verwenden dieselbe Sperre. Ohne reentrante Synchronisation müsste der synchronisierte Code viele zusätzliche Vorkehrungen treffen, um zu verhindern, dass ein Thread blockiert wird.

Source

+1

Auch ein einzelner Thread wird niemals einen Deadlock erzeugen. –

+0

Der folgende Link hat mich glauben lassen: http://stackoverflow.com/questions/437620/java-synchronized-methods-lock-on-object-or-class –

+0

Ich stimme @KirkWoll. Aber ich habe eine Frage. Bedeutet das, dass ein Thread mehrere statische Objekte gleichzeitig sperren kann? – noMAD

1


Nicht sicher so, warum Sie denken, „wenn Thread t1 Schlösser statisches Objekt Firstdata, er hat eine Sperre für die Klasse erworben“. t1 erwirbt eine Sperre für firstData, nicht für die umschließende Klasse. Es gibt keinen möglichen Deadlock in Ihrem Code, wie es ist.

EDIT
Ihren Kommentar Nachfolgend wird die Verbindung über den Unterschied zwischen diesen zwei Erklärungen:

public synchronized method() // lock on the instance (this) 
public static synchronized method() // lock on the class (Myclass.class) 

Aber es gibt keinen Zusammenhang mit Deadlocks.

+0

Der folgende Link hat mich glauben lassen http://stackoverflow.com/questions/437620/java-synchronized-methods-lock-on-object-or-class –

+0

@assylias: Könnten Sie bitte erklären, welches Objekt gesperrt wird, wenn t1 erwirbt Sperre auf 'FirstData' (statisches Feld) ... meinst du nur das Objekt firstData wird gesperrt? ... Weder die Klasse noch das Container DeadlockRunnable-Objekt? –

+0

@ tm.sauron Ja - eine Sperre ist an ein bestimmtes Objekt gebunden, in diesem Fall 'firstData' und' secondData' - die einschließende Klasse 'DeadlockRunnable' spielt hier keine andere Rolle als ein Code-Container ... – assylias