我只需要确认我已正确理解同步块中锁的概念。 首先,我将告诉我的理解。 获取对象的锁意味着没有其他线程可以访问对象类的同步代码。在同步方法的情况下,Threads获取对用于调用该方法的对象的锁定(即,隐含地为该引用)。这意味着其他线程无法访问当前对象的类的同步代码。但是,在同步块的情况下,我们可以指定我们希望线程获取锁的对象。
现在假设我们在A类中的方法中同步了块,获取了对B类对象的锁定。因此,假设一个线程进入此同步块并获取了B类特定对象的锁定。
如果任何其他线程使用B类的同一对象,它将无法进入A类中的synchronized块,对吧? 而且其他线程也无法访问B类中的任何同步代码?
那么A类中的其他同步代码呢?因为线程已经获得了对B类对象的锁定,其他线程可以访问A类的其他同步代码吗?这意味着A类对象没有锁定,只有B类?
我希望人们理解我的问题。
提前致谢。
答案 0 :(得分:2)
获取锁定 对象意味着没有其他线程可以 访问的同步代码 对象的类。
这并非严格属实。如果代码在不同的对象实例上同步,则另一个线程可以执行属于对象类的同步代码。锁仅限制在同一实例上同步的线程。
现在,如果您正在讨论同步(非静态)方法,那么将被锁定的对象是被调用方法的this
。但适用相同的规则。
现在让我们说我们已经同步了 阻止A类获取中的方法 锁定B类对象。所以让我们 说一个线程输入此 同步块并已获得 一个特定对象的锁定 B级。
如果任何其他线程使用相同的 B类的对象将无法实现 进入同步块 A级,对吗?还有另一个 线程也不能访问任何 B类中的同步代码?
如果“其他线程”在同一个B实例上同步,则第一部分是正确的。否则它是不正确的。
第二部分不正确。它只是在被阻止的B的同一个实例上同步的代码。
答案 1 :(得分:1)
首先,我认为你最好不要把对话带出来。假设您有两个对象o1
和o2
,这些对象实际上与讨论无关,并且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
}
}
如果你总是考虑同步块和被用作锁的实际实例,那么事情在我看来就更简单了。线程可以锁定任何对象,两个线程无法访问由同一对象锁定的同步区域。