锁定同步块

时间:2009-11-29 07:22:07

标签: java multithreading synchronization locking

我只需要确认我已正确理解同步块中锁的概念。 首先,我将告诉我的理解。 获取对象的锁意味着没有其他线程可以访问对象类的同步代码。在同步方法的情况下,Threads获取对用于调用该方法的对象的锁定(即,隐含地为该引用)。这意味着其他线程无法访问当前对象的类的同步代码。但是,在同步块的情况下,我们可以指定我们希望线程获取锁的对象。

现在假设我们在A类中的方法中同步了块,获取了对B类对象的锁定。因此,假设一个线程进入此同步块并获取了B类特定对象的锁定。

如果任何其他线程使用B类的同一对象,它将无法进入A类中的synchronized块,对吧? 而且其他线程也无法访问B类中的任何同步代码?

那么A类中的其他同步代码呢?因为线程已经获得了对B类对象的锁定,其他线程可以访问A类的其他同步代码吗?这意味着A类对象没有锁定,只有B类?

我希望人们理解我的问题。

提前致谢。

2 个答案:

答案 0 :(得分:2)

  

获取锁定   对象意味着没有其他线程可以   访问的同步代码   对象的类。

这并非严格属实。如果代码在不同的对象实例上同步,则另一个线程可以执行属于对象类的同步代码。锁仅限制在同一实例上同步的线程。

现在,如果您正在讨论同步(非静态)方法,那么将被锁定的对象是被调用方法的this。但适用相同的规则。

  

现在让我们说我们已经同步了   阻止A类获取中的方法   锁定B类对象。所以让我们   说一个线程输入此   同步块并已获得   一个特定对象的锁定   B级。

     

如果任何其他线程使用相同的   B类的对象将无法实现   进入同步块   A级,对吗?还有另一个   线程也不能访问任何   B类中的同步代码?

如果“其他线程”在同一个B实例上同步,则第一部分是正确的。否则它是不正确的。

第二部分不正确。它只是在被阻止的B的同一个实例上同步的代码。

答案 1 :(得分:1)

首先,我认为你最好不要把对话带出来。假设您有两个对象o1o2,这些对象实际上与讨论无关,并且o1引用了o2。< / p>

如果o1同步实例o2上的块,则其他任何线程都无法进入同一实例o2上的同步部分。这可以是o2的非静态同步方法,也可以是请求锁定同一对象的任何同步块(假设有一个o3对象也引用o2并且想要同步它,它将被阻止,直到o1释放锁定。

可能让你困惑的是围绕同步方法的语法糖。 synchronized方法只是一种方法,编译器在您调用方法的实际实例上添加一个synchronized块,它覆盖整个方法体。

public synchronized void synch1() {
   // body
}
// equivalent to:
public void synch2() {
   synchronized( this ) {
      // body
   }
}

如果你总是考虑同步块和被用作锁的实际实例,那么事情在我看来就更简单了。线程可以锁定任何对象,两个线程无法访问由同一对象锁定的同步区域。