2014-06-29 100 views
0

如果我編寫一個「擴展線程」的類,並且該類的每個對象實例都有另一個類的對象變量。例如:包含其他對象的對象的同步方法

public class MyClass extends Thread{ 

    private int num; 
    private MyClass2 obj; 
    public MyClass(int num, MyClass2 obj){ 
    this.num = num; 
    this.obj = obj; 
    } 

這個類裏面我寫了使用MyClass2方法的同步方法。例如:

public synchronized int doSomething(){ 
    obj.someMethod(); 
    } 

我的問題是:

1)當我打電話類MyClass2方法從同步方式,它仍將同步和原子,或者,當它熄滅其他不同步方法會繼續與其他線程? 2)如果它會停止同步...並且我希望它是同步的,我需要在類「MyClass2」中使「someMethod」同步嗎? 3)如果我聲明瞭兩個不同的「MyClass」類對象,但它們都有相同的「MyClass2」對象,如果調用doSomething方法,它們會被同步?

回答

2

你可以考慮爲synchronized方法:

public int doSomething(){ 
    synchronized(this) //this is the protected object 
    { 
     obj.someMethod(); 
     //Whatever other code you my have within doSomething 
    } 
} 

沒有兩個同步的區域可以在同一時間運行,如果它們引用的保護對象,但這並不避免不同步的代碼使用這個對象。

要回答你的問題:

  • (問題1和2)非同步,而不需要通過保護對象同步方面的方法或方法(在你的情況this)不會被阻塞時,你的synchronized方法是運行。
  • (問題3)否,他們不會,在這種情況下,您需要保護obj,因爲同步方法的隱式保護對象是this,即其方法正在調用的實例。

如果obj參考在不同MyClass情況下使用時,您必須對對象的任何同步訪問:

public int doSomething() { 
    synchronized(obj) //Now, obj is the protected object 
    { 
     obj.someMethod(); 
    } 
} 
0

找到我下面的評論。 1)當我從同步方法調用類MyClass2中的方法時,它仍然是同步的和原子的,或者當它出去用於其他不同步的方法時,它將繼續與其他線程? 編號MyClass2中的方法不同步。你需要明確地做到這一點

2)如果它將停止同步...我希望它是同步的,我需要使「MyMlass2」類中的「someMethod」也同步嗎?

是的。 「someMethod」應該同步

3)如果我聲明瞭兩個不同的類「MyClass」的對象,但它們都具有相同的「MyClass2」對象,如果調用doSomething方法,它們將被同步?

每個線程獲取因此相同的數據沒有線程之間共享新MyClass2對象。無需同步。雖然「的someMethod」同步這是沒有意義的,因爲每個對象都有它自己的鎖

運行下面的代碼,並檢查自己做的變化。

class MyClass extends Thread{ 

    private int num; 
    private MyClass2 obj; 
    public MyClass(int num, MyClass2 obj){ 
     this.num = num; 
     this.obj = obj; 
    } 

    public synchronized void doSomething(){ 
     obj.someMethod(this.num); 
    } 

    public void run(){ 
     doSomething(); 
    } 
} 

class MyClass2{ 
    public synchronized void someMethod(int i){ 
     System.out.println(i+"--"+Thread.currentThread().getName()); 
     for(int j=0;j<10;j++){ 
      System.out.print(j);  
     } 
     System.out.println(); 
    } 
} 

public class Main{ 
    public static void main(String[] arg){ 
     MyClass2 m=new MyClass2(); 
     for(int i=0;i<20;i++){ 
      new MyClass(i,m).start(); 
     } 
    } 
} 
相關問題