我知道Java中的destroy()方法已被弃用,但我只是想知道在我们调用线程的destroy方法后,线程是否持有特定对象的锁。销毁会终止线程,那么为什么该对象上的锁没有被释放呢?
当线程死了,为什么对象仍然保持锁定状态?
Thread::destroy
(在 Java 7 中)的
javadoc是这样说的:
已弃用。这个方法最初是为了销毁这个线程而不进行任何清理。它所持有的任何监视器都会保持锁定状态。 但是,该方法从未被实现过。 如果要实现的话,就会像 suspend() 一样容易出现死锁。如果目标线程在关键系统资源被销毁时持有保护该资源的锁,则任何线程都无法再次访问该资源。如果另一个线程试图锁定该资源,就会导致死锁。这种死锁通常表现为“冻结”进程。
所以,你的问题没有实际意义。
该方法未实施。不可能明确地说出会是什么样的行为。只是他们最初的意图。
话虽如此,所声明的意图是不会对
destroy()
进行清理,意思是:
synchronized
获取的原始锁不会被释放,finally
块不会被执行,并且try
管理的“资源”资源不会被关闭。javadoc 说,如果你在
destroy()
上调用 Thread
,则行为是抛出 NoSuchMethodError
。将发生正常的异常行为。原始锁将被释放,等等。
但是...只是...不要。
最后,如果您谈论的是
Lock
对象而不是原始锁,那么只有当您的代码显式调用 Lock::unlock
时,这些对象才会被释放。 Lock
的 javadoc建议您像这样使用
try ... finally
进行锁定和锁定:
Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}
...“在大多数情况下”。如果您始终使用此习惯用法,那么您可以确保当线程终止时,所有锁都将始终被释放。 (但如果
destroy()
按设想实施,那就行不通了。)
在此示例中,您可以看到线程终止时锁并未释放:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
public class CheckThreadLock {
public static void main(String[] args) {
final Lock reentrantLock = new ReentrantLock();
Thread myThread = new Thread() {
@Override
public void run() {
System.out.println(Thread.currentThread()+": myThread acquire lock");
reentrantLock.lock();
System.out.println(Thread.currentThread()+": Lock aquired: wait...");
LockSupport.parkNanos(1_000_000_000);
System.out.println(Thread.currentThread()+": Quiting thread");
}
};
myThread.start();
LockSupport.parkNanos(500_000_000);
System.out.println(Thread.currentThread()+": Acquire lock");
reentrantLock.lock();
System.out.println(Thread.currentThread()+"; Success!");
}
}
输出:
Thread[Thread-0,5,main]: myThread acquire lock
Thread[Thread-0,5,main]: Lock aquired: wait...
Thread[main,5,main]: Acquire lock
Thread[Thread-0,5,main]: Quiting thread
//Success never happens because of deadlock