当线程被销毁时,为什么对象上的锁仍然处于活动状态?

问题描述 投票:0回答:2

我知道Java中的destroy()方法已被弃用,但我只是想知道在我们调用线程的destroy方法后,线程是否持有特定对象的锁。销毁会终止线程,那么为什么该对象上的锁没有被释放呢?

当线程死了,为什么对象仍然保持锁定状态?

java multithreading locking
2个回答
4
投票

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()
按设想实施,那就行不通了。)


1
投票

在此示例中,您可以看到线程终止时锁并未释放:

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
© www.soinside.com 2019 - 2024. All rights reserved.