2013-05-26 41 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");