multithreading - 获取对象监视器锁的线程是否也获取超类的对象锁?
问题描述
当一个线程获取一个对象的监视器锁(比如 B 类)时,它是否获取属于它的超类(比如 A 类,其中 B 扩展 A)的对象的监视器锁?
观察 #1 - 当一个线程(通过同步方法拥有派生对象 B 的监视器锁)在超类 A 中调用 wait() 时,第二个线程获取对象 B 的监视器锁并在 A 中等待。最后,两个线程都退出 B同时进行对象监控。
我的理解是线程应该调用
wait()
它拥有锁的对象,否则这将导致 IllegalMonitorStateException。在A的实例方法中调用wait()时没有异常的原因,是否意味着拥有B对象锁的线程也拥有A对象的锁,它是超类?
已查看有关同步和内在锁的文章 -内在锁对 Java 类实际上意味着什么? https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
public class Obs2 {
public static void main(String[] args) {
A a = new B();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start(); t2.start();
}
}
class A implements Runnable {
public void run() {
try {
wait(2000); // OK; No IllegalMonitorStateException
} catch (InterruptedException e) {}
}
}
class B extends A {
@Override
public synchronized void run() {
super.run();
}
}
观察 #2 - 当线程(通过同步方法拥有对象 A 的监视器锁)在任意类 C 中调用 wait() 时,它会引发 IllegalMonitorStateException。
这表明线程在 C 的对象上调用 wait(),而它拥有不同的对象 A 的锁。因此例外。
public class Obs2 {
public static void main(String[] args) {
A a = new A();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start(); t2.start();
}
}
class A implements Runnable {
public synchronized void run() {
(new C()).display(this);
}
}
class C {
public void display() {
try {
wait(2000); //--> will lead to IllegalMonitorStateException
} catch (InterruptedException e) {}
}
}
与任何其他类相比,为什么超类的对象监视器锁的行为方式存在这种固有差异?
我对对象监视器锁的理解是否遗漏了什么?
解决方案
我不确定你的问题是否有意义。没有“超类”实例这样的东西,因为子类的实例是一个并且与其超类的实例相同,否则每次使用new
关键字时都会实例化多个对象。这也是您不能执行以下操作的原因:
synchronized (super) {
}
最终,使用wait
和notify[All]
所属的能力Object
(因为它们是最终方法),这是每个类的超超类。您可以将同步this
视为在属于 的监视器上进行同步Object
,因为内部锁与对象相关联,而不是与类相关联(一个重要的区别是Class
可以获取与对象相关联的内部锁)。
因此,由于A
和B
都是 的同一个实例,因此您是否已同步并调用fromObject
并不重要,它们都指的是同一个。B
wait
A
Object
推荐阅读
- unix - 根据起始字母过滤掉单词
- vue.js - 我将如何为可嵌入的 Vue 应用程序优化 SEO?
- laravel - 与 Laravel Jetstream 一起使用时,未编译 Tailwind 颜色
- firebase - 如何从卡上的 Firebase 检索数据并将数据提取到详细信息屏幕?
- docker - 如何要求用户登录才能推送到 docker 注册表?
- javascript - Fetch 返回 null 但页面刷新后返回对象。如何解决?
- javascript - 如何获取数组值并将其设置在我的内部 html 中?
- python - 以管理员身份启动后 Python 程序未运行
- c - 嵌入式 C 项目无法连接到 googleapis.com
- simics - Simics 使用 SMM 吗?