2013-01-21 59 views
17

java中的監視器是不是限制對實例變量的訪問,並且只限於在同步語句中聲明同步或代碼的方法?java監視器是否包含實例變量?

我創建了兩個線程,thread y調用同步方法,它聲明同步,而thread r調用未聲明同步的異步方法。都調用共享對象s上的方法。

Thread r能夠修改對象s的實例變量,同時該對象的監視器或鎖定仍由thread y保存。

Java中的監視器是不是限制對實例變量的訪問,並且僅限於在同步語句中聲明同步或代碼的方法?

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

的程序的輸出是下面:

 
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 

回答

16

是的。保持對象的監視器可以防止另一個線程執行另一個代碼塊或在同一個對象上進行同步。如果某個方法不同步,則任何線程都可以隨時調用它,而不管另一個線程是否擁有監視器。

如果有至少一個線程修改此共享狀態的機會,則必須同步對共享聲明(即使只讀訪問)的每次訪問。

3

是否該監視器在Java不限制訪問實例變量和僅向在同步聲明爲同步或代碼的方法的聲明?

是的。

同步塊(或方法)是互相排斥的。這並不妨礙用作鎖的對象(監視器,我們稱之爲lock)在這些塊之外使用,在這種情況下不會執行同步。例如,一個線程可以讀取或寫入lock,而另一個線程在同步塊內,其中lock是監視器。

如果您想要限制對變量的訪問,您需要確保所有訪問都是在持有鎖的情況下進行的(任何鎖,只要每次訪問都相同)。

2

同步製作方法有兩個作用:

首先,它是不可能的同一對象上同步方法來交錯兩個調用。當一個線程正在執行一個對象的同步方法時,所有其他線程調用同一對象的同步方法塊(掛起執行),直到第一個線程完成對象。其次,當一個同步方法退出時,它會自動建立一個與先前關聯的同步對象的任何後續調用同步方法。這保證了對所有線程都可見的對象狀態的更改。

(來源:the Java tutorials

相關問題