获取对象监视器锁的线程是否也获取父类的对象锁?
Does a thread acquiring monitor lock of object also acquires the object lock of superclass?
当一个线程获取一个对象的监视器锁(比如class B)时,它是否获取属于它的超级对象的监视器锁class(比如class A, B 延伸 A) ?
Observation #1 - When a thread (that owns the monitor lock of derived object B through synchronized method) calls wait() inside superclass A, the second thread acquires object B's monitor lock and goes for waiting in A. Finally, both threads exit B's object monitor at the same time.
My understanding is a thread should invoke wait()
on an object whose lock it owns, else this will lead to IllegalMonitorStateException. The reason that there being no exception while wait() called inside A's instance method, does it mean the thread owning the B object lock also owns the lock of A object, it's superclass ?
已查看有关同步和内部锁的文章 -
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();
}
}
Observation #2 - When a thread (that owns monitor lock of object A through synchronized method) invokes wait() inside any arbitrary class C, it raises an IllegalMonitorStateException.
This suggests the thread calls wait() on C's object whereas it owns the lock for object A which are different. Hence the exception.
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) {}
}
}
为什么与任何其他 class 相比,超级 class 对象监视器锁的行为方式存在固有差异?
我对对象监视器锁的理解是否遗漏了什么?
我不确定你的问题是否有意义。没有 "superclass" 实例这样的东西,因为 subclass 的实例与它的 superclass 的实例是同一个,否则你每次都会实例化几个对象使用 new
关键字。这也是为什么你不能做类似的事情的原因:
synchronized (super) {
}
最终,使用wait
和notify[All]
的能力属于Object
(因为它们是final方法),这是每个方法的超级超级class class。您可以将 this
上的同步视为在属于 Object
的监视器上进行同步,因为内部锁与对象相关联,而不是 classes(一个重要的区别是内部锁与可能会获得一个 Class
对象。
因此,由于 A
和 B
都是 Object
的同一个实例,因此您在 B
中同步并调用 wait
来自 A
,它们指的是同一个 Object
.
当一个线程获取一个对象的监视器锁(比如class B)时,它是否获取属于它的超级对象的监视器锁class(比如class A, B 延伸 A) ?
Observation #1 - When a thread (that owns the monitor lock of derived object B through synchronized method) calls wait() inside superclass A, the second thread acquires object B's monitor lock and goes for waiting in A. Finally, both threads exit B's object monitor at the same time.
My understanding is a thread should invoke
wait()
on an object whose lock it owns, else this will lead to IllegalMonitorStateException. The reason that there being no exception while wait() called inside A's instance method, does it mean the thread owning the B object lock also owns the lock of A object, it's superclass ?
已查看有关同步和内部锁的文章 -
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();
}
}
Observation #2 - When a thread (that owns monitor lock of object A through synchronized method) invokes wait() inside any arbitrary class C, it raises an IllegalMonitorStateException.
This suggests the thread calls wait() on C's object whereas it owns the lock for object A which are different. Hence the exception.
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) {}
}
}
为什么与任何其他 class 相比,超级 class 对象监视器锁的行为方式存在固有差异?
我对对象监视器锁的理解是否遗漏了什么?
我不确定你的问题是否有意义。没有 "superclass" 实例这样的东西,因为 subclass 的实例与它的 superclass 的实例是同一个,否则你每次都会实例化几个对象使用 new
关键字。这也是为什么你不能做类似的事情的原因:
synchronized (super) {
}
最终,使用wait
和notify[All]
的能力属于Object
(因为它们是final方法),这是每个方法的超级超级class class。您可以将 this
上的同步视为在属于 Object
的监视器上进行同步,因为内部锁与对象相关联,而不是 classes(一个重要的区别是内部锁与可能会获得一个 Class
对象。
因此,由于 A
和 B
都是 Object
的同一个实例,因此您在 B
中同步并调用 wait
来自 A
,它们指的是同一个 Object
.