2013-01-21 6 views
17

È che il monitor in Java non limita l'accesso alle variabili di istanza e solo ai metodi dichiarati sincronizzati o al codice nelle istruzioni sincronizzate?Il monitor java include variabili di istanza?

Ho creato due thread, thread y invoca il metodo di sincronizzazione, che viene dichiarato sincronizzato mentre thread r richiama il metodo unsync che non è dichiarato sincronizzato. Entrambi richiamano i metodi sull'oggetto condiviso s.

Thread r è in grado di modificare la variabile di istanza dell'oggetto s mentre il monitor o il blocco di tale oggetto è ancora trattenuto dallo thread y.

Il monitor in Java non limita l'accesso alle variabili di istanza e solo ai metodi dichiarati sincronizzati o al codice nelle istruzioni sincronizzate?

public class stuff { 

    private int a = 10; 

    public synchronized void sync() { 
     long t1 = System.currentTimeMillis(); 
     System.out 
       .println("Okay, I am in sync method. I will be waiting for 10 seconds. Current Time = " 
         + System.currentTimeMillis()); 
     while (System.currentTimeMillis() - t1 < 10000); 
     System.out 
       .println("Okay, I have waited for 10 seconds. Current time is " 
         + System.currentTimeMillis() 
         + ".Now I will exit from sync method, a= " + this.a); 
    } 

    public void unsync() { 
     System.out 
       .println("Alright, I am in unsync method the currrent time is " 
         + System.currentTimeMillis()); 
     this.a = this.a + 1; 
     System.out.println("The time of exit from unsync method is " 
       + System.currentTimeMillis()); 

    } 
} 

class t1 extends Thread { 
    stuff s; 

    public t1(stuff s) { 
     this.s = s; 
    } 

    public void run() { 
     s.sync(); 
    } 
} 

class t2 extends Thread { 
    stuff s; 

    public t2(stuff s) { 
     this.s = s; 
    } 

    public void run() { 
     s.unsync(); 
    } 
} 

class m { 
    public static void main(String args[]) throws Exception { 
     stuff s = new stuff(); 
     t1 y = new t1(s); 
     t2 r = new t2(s); 
     y.start(); 
     Thread.sleep(2000); 
     r.start(); 
    } 
} 

L'output del programma è qui sotto:

 
Okay, I am in sync method. I will be waiting for 10 seconds. Current Time = 1358801766310 
Alright, I am in unsync method the currrent time is 1358801768343 
The time of exit from unsync method is 1358801768343 
Okay, I have waited for 10 seconds. Current time is 1358801776310.Now I will exit from sync method, 
a= 11 

risposta

16

Sì. Tenere il monitor di un oggetto impedisce a un altro thread di eseguire un altro blocco di codice o sincronizzato sullo stesso oggetto. Se un metodo non è sincronizzato, qualsiasi thread può chiamarlo in qualsiasi momento, indipendentemente dal fatto che un altro thread abbia o meno un monitor.

Ogni accesso a un accesso condiviso, anche se di sola lettura, deve essere sincronizzato se esiste la possibilità che almeno un thread modifichi questo stato condiviso.

3

è che il monitor in Java non limitare l'accesso a variabili di istanza e solo per i metodi che vengono dichiarati sincronizzati o codice a sincronizzato affermazioni?

Sì.

I blocchi (oi metodi) sincronizzati sono, tra l'altro, mutuamente esclusivi. Ciò non impedisce l'utilizzo dell'oggetto come blocco (il monitor, chiamiamolo lock) da utilizzare al di fuori di tali blocchi, nel qual caso non verrà eseguita alcuna sincronizzazione. Ad esempio, un thread può leggere o scrivere lock mentre un altro thread si trova all'interno di un blocco sincronizzato dove lock è il monitor.

Se si desidera limitare l'accesso a una variabile, è necessario assicurarsi che tutti gli accessi siano effettuati tenendo un lucchetto (qualsiasi blocco, purché sia ​​lo stesso per ogni accesso).

2

metodi che fanno sincronizzati ha due effetti:

primo luogo, non è possibile che due invocazioni di metodi sincronizzati sullo stesso oggetto per interlacciare. Quando un thread sta eseguendo un metodo sincronizzato per un oggetto, tutti gli altri thread che invocano metodi sincronizzati per lo stesso blocco oggetto (sospendi l'esecuzione) finché il primo thread non viene eseguito con l'oggetto.

In secondo luogo, quando un metodo sincronizzato viene chiuso, stabilisce automaticamente una relazione prima-evento con qualsiasi successiva chiamata di un metodo sincronizzato per lo stesso oggetto. Ciò garantisce che le modifiche allo stato dell'oggetto siano visibili a tutti i thread.

(fonte: the Java tutorials)