2014-03-05 125 views
0

感覺很好成爲這個社區的一部分。已經閱讀了很多答案,清除了我對許多問題的疑惑,但沒有找到一個答案。我知道同步是如何在Java中工作的,但是當線程通過另一個類調用同步方法時,會發現錯誤的行爲。線程通過另一個類調用同步方法時會發生什麼?

PSB我試過的:

A類同步方法「meth1」。與非synhronized法 「meth2」

package threadinterview; 

public class B { 
public void meth2() { 
    A a1 = new A(); 
    a1.meth1(); 
} 
} 

主要類

package threadinterview; 

public class A { 
public synchronized void meth1() 
{ 
    for(int i=0; i<3; i++) 
    { 
     System.out.println("meth1: " + Thread.currentThread().getName()); 
     try { 
      Thread.sleep(2000); 
     } catch (InterruptedException e) { 
      System.out.println("Interrupted: " + Thread.currentThread().getName()); 
     } 
    } 
} 

B級在這種情況下運行該項目

package threadinterview; 
public class ThreadImpl { 
public static void main(String[] args) { 
    final B b1 = new B(); 
    final B b2 = new B(); 

    new Thread(new Runnable() { 

     @Override 
     public void run() { 
      b1.meth2(); 
     } 
    }).start(); 

    new Thread(new Runnable() { 

     @Override 
     public void run() { 
      b1.meth2(); 
     } 
    }).start(); 
} 
} 

現在,即使我最終運行同步方法,我看不到同步的效果。在這裏我所得到的,當我運行程序:

meth1: Thread-0 
meth1: Thread-1 
meth1: Thread-0 
meth1: Thread-1 
meth1: Thread-0 
meth1: Thread-1 

而且,如果我做了synchronized方法靜態爲好,然後我得到了一流水平鎖,可以看到的地方同步效果。我嚴重不明白爲什麼類級鎖定工作,但在這種情況下對象級別不起作用。

回答

2

每次調用

public void meth2() { 
    A a1 = new A(); 
    a1.meth1(); 
} 

創建一個新的A對象。​​上的方法在this上同步對象本身。因此,您正在同步不同的對象。一個同步調用不會阻止另一個同步調用,因爲兩個線程都獲得不同的監視器。

+0

明白了。不難,但沒有點擊。萬分感謝。 :) – user3384573

0

我認爲你誤解了'同步效應'。在你的例子中,你從兩個獨立的線程中調用B.meth2()。此方法創建類A的新實例,然後調用A.meth1()。現在無論你想要在meth1()上執行什麼鎖定(這在你的例子或描述中都不是很清楚),它是無關緊要的,因爲你在類A的兩個不同實例上調用它,即隱式使用兩個不同的鎖。

相關問題