停放 JAVA 线程是否会导致释放任何获取的监视器
Does parking a JAVA thread cause any acquired monitors to be released
当通过停放线程暂停线程执行时,是否会导致线程放弃任何获取的对象监视器的所有权?
简而言之,如果线程 (t1) 获取 'this' 对象的监视器并被停放,而另一个线程 (t2) 试图通过首先尝试获取监视器来取消停放 t1,则以下代码是否会死锁监控 'this' 和阻塞。
// Thread t1 executes this code first.
syncronized(this) {
LockSupport.park();
}
// Thread t2 then executes this piece of code.
synchronized(this) {
LockSupport.unpark(t1);
}
会出现死锁,因为 t1
被阻塞并且在 t2
试图获取同一锁时仍然拥有 this
对象上的锁。
那是没有意义的。
有时一个线程需要同时持有多个锁。一些糟糕的遗留代码可能会做这样的事情:
synchronized(objectA) {
lockB.lock();
try {
doSomethingThatRequiresOwnershipOfBothLocks();
} finally {
lockB.unlock();
}
}
如果lockB.lock()
调用临时解锁objectA上的监视器,则不会解决任何问题。
当通过停放线程暂停线程执行时,是否会导致线程放弃任何获取的对象监视器的所有权?
简而言之,如果线程 (t1) 获取 'this' 对象的监视器并被停放,而另一个线程 (t2) 试图通过首先尝试获取监视器来取消停放 t1,则以下代码是否会死锁监控 'this' 和阻塞。
// Thread t1 executes this code first.
syncronized(this) {
LockSupport.park();
}
// Thread t2 then executes this piece of code.
synchronized(this) {
LockSupport.unpark(t1);
}
会出现死锁,因为 t1
被阻塞并且在 t2
试图获取同一锁时仍然拥有 this
对象上的锁。
那是没有意义的。
有时一个线程需要同时持有多个锁。一些糟糕的遗留代码可能会做这样的事情:
synchronized(objectA) {
lockB.lock();
try {
doSomethingThatRequiresOwnershipOfBothLocks();
} finally {
lockB.unlock();
}
}
如果lockB.lock()
调用临时解锁objectA上的监视器,则不会解决任何问题。