2

在下面的示例中,在实例变量employee 上获得了锁(不是在this 上),但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();
}
}
4

4 回答 4

5

You are using the same TestClass1 instance for both threads, therefore they are using the same Employee instance to lock on.

To get them to use different locks, you need to do:

Thread t1 = new Thread(new TestClass1(), "T1");
Thread t2 = new Thread(new TestClass1(), "T2");
于 2013-05-26T11:41:19.830 回答
2

Both threads use the same instance of TestClass1. So internally they share the same employee instance. To avoid this create a new instance for each Thread.

于 2013-05-26T11:42:09.960 回答
2

You are using the same object (employee) for your synchronization. It means that indeed of one thread entered the synchronized block other thread will be locked until the first frees the lock. It does not matter whether you are using this or any other object. What does matter is that this is the same object.

This is the purpose of synchronization. If access to specific object should be synchronized because the data may be inconsistent if 2 or more threads use this data simultaneously we use synchronization.

于 2013-05-26T11:43:55.740 回答
0

您正在做的是创建一个Runnbable对象并从中制作两个Thread对象。为线程分配两个不同的名称不会使它们成为两个线程,相反,为两个线程分配相同的名称不会使它们成为一个线程。

基本上,您正在创建一个具有相同资源的重复线程。

因此,您的第一个线程锁定到employee并且第二个线程(实际上与Runnable获得锁定的第一个线程相同)请求锁定employee. 所以,它被阻塞了。

正在发生的事情是Runnable请求锁定自身。

就像 Keppil 建议的那样:

Thread t1 = new Thread(new TestClass1(), "T1");
Thread t2 = new Thread(new TestClass1(), "T2");
于 2013-05-26T11:49:58.943 回答