Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同步块中的锁_Java_Multithreading_Synchronization_Locking - Fatal编程技术网

Java 同步块中的锁

Java 同步块中的锁,java,multithreading,synchronization,locking,Java,Multithreading,Synchronization,Locking,我只需要确认我已经正确理解了同步块中锁的概念。 首先,我会告诉你我所理解的。 获取对象的锁意味着没有其他线程可以访问对象类的同步代码。在同步方法的情况下,线程获取用于调用方法的对象的锁(即隐式地调用此引用)。这意味着其他线程无法访问当前对象类的同步代码。但是,对于同步块,我们可以指定希望线程获取锁的对象 现在,假设我们在类a中的一个方法中有一个同步块,它获得了类B对象的锁。因此,假设一个线程进入这个同步块,并获得了类B特定对象的锁 如果任何其他线程使用类B的相同对象,它将无法进入类A中的同步块,

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

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

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

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

我希望人们理解我的问题

提前谢谢

获得一把锁 对象表示没有其他线程可以 访问的同步代码 对象的类

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

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

现在让我们假设我们已经同步了 类中的方法中的块 类B对象上的锁。因此让 假设有一条线进入这个 已同步块并已获取 锁定某一特定对象的锁 B类

如果任何其他线程使用相同的 B类的对象,它将无法 要在中输入同步块,请执行以下操作: 甲级,对吗?还有另一个 线程也不能访问任何 B类中的同步代码

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


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

首先,我认为您最好从对话中删除单词class。让我们假设您有两个对象
o1
o2
,它们是实际与讨论无关的类的实例,
o1
引用了
o2

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

可能让您感到困惑的是同步方法周围的语法糖分。同步方法就是编译器在调用该方法的实际实例上添加一个同步块的方法,它覆盖了整个方法体

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

如果您总是从同步块和用作锁的实际实例的角度来考虑,那么在我看来事情就简单多了。一个线程可以锁定任何对象,两个线程不能访问同一对象锁定的同步区域。

类与类无关(遗憾的是,在
对象-D'oh上标记为同步锁定的静态方法除外)。将锁视为每个对象都带有最终引用的另一个对象(这是一个糟糕的设计!),锁定对象并不意味着不使用锁的代码无法访问对象的字段。“只有在同一个被阻止的B实例上同步的代码。”那么您的意思是类B的对象上同步的类A中的代码将被阻止。如果类B本身有同步代码,它不会被阻止吗?我有这个问题,因为我们正在获得的是B类对象的锁。该锁还应阻止calss B中的同步代码。不是吗?不是。我的意思是只有在同一个B对象上同步时才会被阻止。关键是代码的位置是不相关的;唯一重要的是你正在同步的对象。因此,如果线程获得了对象上的锁,那么在该对象上同步的所有代码都将在代码所在的任何位置被阻止。