Java同步问题

时间:2010-09-11 16:10:30

标签: java multithreading synchronization

我是Java Threads和同步的新手。

让我说我有:

public class MyClass(){

    public synchronized void method1(){ 
        //call method2();
    } 

    public synchronized void method2(){};

}
  1. 在实例对象上同步method1()时意味着什么?因此,当一个线程在尝试访问synchronized method1()时获取锁定时,是否会阻止其他线程从该同一对象访问另一个synchronized method2()

  2. 让我们说一个线程在访问method1()时获取一个锁,但是让我们说method1()打电话给method2()也是synchronized。这有可能吗?我的意思是否有任何规则可以阻止method1()调用method2()

  3. 提前致谢。

4 个答案:

答案 0 :(得分:7)

  1. 是的,在非静态方法上使用synchronized方法修饰符意味着它使用调用该方法的实例的监视器,并在所有此类方法之间共享。
  2. 否 - 线程已拥有监视器,因此可以自由输入受同一监视器保护的其他块。

答案 1 :(得分:4)

  1. See here

      

    对同一对象的两个同步方法的调用不可能进行交错。当一个线程正在为对象执行同步方法时,所有其他线程调用同一对象的同步方法(暂停执行)直到第一个线程完成对象。

  2. 由于此线程持有当前对象的锁,因此可以调用method2(),而其他线程也无法调用。

答案 2 :(得分:2)

关于问题2的注释,method1()也可以在其他类中调用同步方法,这可能会导致死锁:

Thread1调用synchronized方法1(),后者又需要调用AnotherClass中的synchronized method_b() Thread2持有对AnotherClass的锁定,并且正在执行一个方法,该方法需要在由Thread1持有锁的类中调用method1()

两个线程都会阻塞等待对方释放锁定,这是一个死锁。

答案 3 :(得分:2)

(1)这相当于:

public void method1(){ 
    synchronized (this) {
        ...
    }
}

因此它在当前实例上同步。如果我们以相同的方式重写method2 ......

public void method2(){ 
    synchronized (this) {
        ...
    }
}

...然后您可以清楚地看到它们锁定在同一个对象上,因此其他线程无法调用method1或method2,直到method1退出其synchronized块。

(2)synchronized块是可重入的,这意味着同一个线程可以输入其他synchronized块,这些块可以锁定同一个对象多次。据我了解,每次输入synchronized块时,Java都会将正在同步的对象上的计数器增加1,并且每次退出synchronized块时,它都会减少它。当该计数器达到0时,锁定被释放。