实例变量同步

时间:2013-05-26 11:38:27

标签: java multithreading thread-synchronization

在下面的示例中,在实例变量employee上获取锁定(不在此上),但在进入synchronized块时,仍然会锁定TestClass1的Threads。任何建议为什么这种行为。据我所知,如果它同步就会被锁定。

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 个答案:

答案 0 :(得分:5)

您对两个线程使用相同的TestClass1实例,因此它们使用相同的Employee实例来锁定。

要让他们使用不同的锁,您需要执行以下操作:

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

答案 1 :(得分:2)

两个线程都使用TestClass1的相同实例。所以内部他们共享相同的employee实例。为避免这种情况,请为每个Thread创建一个新实例。

答案 2 :(得分:2)

您正在使用相同的对象(employee)进行同步。这意味着确实有一个线程进入同步块,其他线程将被锁定,直到第一个释放锁。无论您使用this还是其他任何对象都无关紧要。重要的是这是同一个对象。

这是同步的目的。如果应同步对特定对象的访问,因为如果两个或多个线程同时使用此数据,则数据可能不一致,我们使用同步。

答案 3 :(得分:0)

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

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

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

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

就像Keppil建议的那样:

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