2012-04-19 24 views
6

Secondo la mia comprensione, il seguente codice dovrebbe comportare un deadlock. Il motivo è che, quando il thread t1 blocca oggetto firstData, ha acquisito un blocco sulla classe. Quindi, quando tenta di bloccare un altro oggetto statico secondoData, la richiesta dovrebbe bloccarsi.Blocco di membri statici di una classe

Tuttavia, il programma funziona bene e stampe *** Successfully acquired both the locks

cosa si tratta blocco oggetti statici che im manca qui?

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"); 
      } 
     } 
    } 

} 

Per tutti coloro che hanno risposto che le serrature sono in oggetto, invece che di classe, si prega di dare un'occhiata a this

risposta

14

In primo luogo, si dispone di un errore qui:

Il motivo , quando il thread t1 blocca l'oggetto statico firstData, ha acquisito un blocco sulla classe.

Il blocco di un oggetto statico blocca solo quell'oggetto, non la classe. Stai bloccando due oggetti separati.

Il question you refered to è circa synchronized methods non synchronized statements. Questi due costrutti correlati funzionano in modi leggermente diversi.


secondo luogo, anche se sono stati di blocco sul medesimo oggetto, il codice sarebbe ancora non deadlock (ideone). Le serrature intrinseche sono rientranti. Ciò significa che un thread non si blocca da solo se tenta di prendere lo stesso blocco due volte.

Reentrant sincronizzazione

Ricordiamo che il filo non può acquisire un blocco di proprietà di un altro filo. Ma una discussione può acquisire un blocco che già possiede. Consentire a una discussione di acquisire lo stesso blocco più di una volta abilita la sincronizzazione rientrante. Descrive una situazione in cui il codice sincronizzato, direttamente o indirettamente, richiama un metodo che contiene anche codice sincronizzato e entrambi i set di codici utilizzano lo stesso blocco. Senza la sincronizzazione rientranti, il codice sincronizzato dovrebbe prendere molte precauzioni aggiuntive per evitare che un thread si blocchi da solo.

Source

+1

Inoltre, un singolo thread non produrrà mai un deadlock. –

+0

Il seguente collegamento mi ha fatto credere così: http://stackoverflow.com/questions/437620/java-synchronized-methods-lock-on-object-or-class –

+0

Sono d'accordo con @KirkWoll. Ma ho una domanda. Questo significa che un thread può bloccare più oggetti statici contemporaneamente? – noMAD

1

"quando l'oggetto si blocca filo t1 statica FirstData, ha acquisito un blocco sulla classe"
Non certo perché si pensa così. t1 acquisisce un lock su firstData, non sulla classe contenente. Non c'è deadlock possibile nel tuo codice così com'è.

EDIT
seguito il commento, il link è circa la differenza tra questi 2 dichiarazioni:

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

Ma non c'è alcun legame con deadlock.

+0

Il seguente collegamento mi ha fatto credere in questo modo http://stackoverflow.com/questions/437620/java-synchronized-methods-lock-on-object-or-class –

+0

@assylias: Potresti spiegare quale oggetto viene bloccato quando t1 acquisisce bloccare 'firstData' (campo statico) ... intendevi solo l'oggetto firstData viene bloccato? ... Né la classe né l'oggetto DeadlockRunnable del contenitore? –

+0

@ tm.sauron Sì - un blocco è legato a un oggetto specifico, in questo caso 'firstData' e' secondData' - la classe che include 'DeadlockRunnable' non svolge altro ruolo di un contenitore di codice qui ... – assylias

Problemi correlati