2013-05-26 78 views
2

在下面的例子中,對實例變量僱員(未在此)中獲得鎖,但TestClass1的仍然螺紋,而在進入同步塊被鎖。任何建議爲什麼是這種行爲。據我的理解,如果它的同步是這樣的,它應該被鎖定。同步於實例變量

public class TestClass{ 
    public static void main(String args[]){ 
    TestClass1 obj = new TestClass1(); 
    Thread t1 = new Thread(obj, "T1"); 
    Thread t2 = new Thread(obj, "T2"); 
    t1.start(); 
    t2.start(); 
    } 
} 

class TestClass1 implements Runnable{ 

Employee employee = new Employee(); 

public void myMethod() { 
    synchronized (employee) { 
     try { 
      Thread.sleep(4000L); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

public void myOtherMethod() { 
    synchronized (employee) { 
     try { 
      Thread.sleep(4000L); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

@Override 
public void run() { 
    myMethod(); 
    myOtherMethod(); 
} 
} 
+3

我不明白。你寫他們鎖定在變量,這是預期的行爲。那怎麼了? –

回答

5

您使用的是相同的TestClass1實例兩個線程,因此它們使用相同的Employee實例鎖定。

爲了讓他們用不同的鎖,你需要做的:

Thread t1 = new Thread(new TestClass1(), "T1"); 
Thread t2 = new Thread(new TestClass1(), "T2"); 
+0

到底是什麼,我要說:) –

+0

其實我所瞭解的是同步(這)將鎖定線程工作的同一個對象(根據上面的例子)。但在我的例子中,我一直保持同步(實例變量),那麼,如何線程獲取有關實例變量被鎖定... – Sameer

+0

'同步(這)'不鼓勵:) –

2

兩個線程使用的TestClass1相同的實例。所以在內部他們共享相同的employee實例。爲避免這種情況,請爲每個Thread創建一個新實例。

2

您正在使用相同的對象(employee)爲您的同步。這意味着確實有一個線程進入同步塊,其他線程將被鎖定,直到第一個線程釋放鎖。無論您是使用this還是其他任何對象,都無關緊要。重要的是,這是同一個對象。

這是同步的目的。如果對特定對象的訪問應該同步,因爲如果2個或更多線程同時使用這些數據,那麼數據可能不一致,我們使用同步。

+0

用於創建線程的相同對象。這只是他正在做的重複線程:)它必然會被鎖定 –

0

你在做什麼是創建一個對象Runnbable和做兩個Thread對象出來。爲線程分配兩個不同的名稱不會使它們成爲兩個線程,相反,爲兩個線程分配相同的名稱不會使它們成爲一個線程。

基本上,要創建一個使用相同的資源重複線程。

因此,您的第一個線程鎖定在employee上,第二個線程(實際上與第一個獲取鎖的Runnable相同)請求鎖定employee。所以它被阻塞了。

正在發生的事情是,Runnable請求本身上的鎖。

只要做到爲Keppil建議:

Thread t1 = new Thread(new TestClass1(), "T1"); 
Thread t2 = new Thread(new TestClass1(), "T2");