为什么 JDK 1.1 版本后 Thread.stop()、Thread.suspend() 和 Thread.resume() 方法被弃用

10 Sept 2024 | 4 分钟阅读

Thread 类提供了用于创建和控制线程的构造函数和函数。它作为 Object 类的子类,并实现了 Runnable 接口。

已弃用的方法不再被认为是重要的,并且不应该被使用,因为它们可能在未来的版本中被从类中删除。随着类的演进,它们的 API 会发生变化,这可能包括重命名属性、添加新方法或修改现有方法。为了帮助开发人员从旧 API 迁移到新 API,已弃用的类和方法在文档注释中使用 @deprecated 标签进行标识。

为什么这些方法被标记为已弃用?

Thread.stop()、Thread.suspend() 和 Thread.resume() 方法在 JDK 1.1 后被弃用,因为它们被认为是不安全且潜在危险的。

Thread.stop() 方法用于强制终止线程的执行。然而,它会突然终止线程的执行,可能导致应用程序或系统不一致。突然终止也可能导致资源泄露或其他不良后果。因此,Thread.stop() 方法被弃用了。

Thread.suspend() 方法用于暂时挂起线程的执行。然而,在没有线程协作的情况下挂起线程可能导致线程死锁或其他同步问题。如果一个线程在持有某些资源或锁的情况下被挂起,它可能会阻止其他线程访问这些资源,导致整个应用程序无响应。其固有的风险导致了 Thread.suspend() 方法的弃用。

Thread.resume() 方法用于恢复被挂起线程的执行。然而,在没有适当同步的情况下恢复线程也可能导致同步问题和线程死锁。由于 Thread.suspend() 方法已被弃用,Thread.resume() 方法变得不必要且被弃用。

使用已弃用的线程同步方法导致的死锁

在并发编程中,当多个线程无限期地阻塞,相互等待释放资源时,就会发生死锁。代码示例演示了使用已弃用的线程同步方法导致的死锁场景。

文件名: DeadlockUsingDeprecatedMethods.java

输出

Main Thread 500
Main Thread 501Thread Name: Thread A
Setting value 1 in the data array
Thread A is awake now
Thread Name: Thread A
Setting value 2 in the data array
Thread A is awake now
Thread A is suspending

解释:提供的代码创建了 thread1 和 thread2,它们操作共享的 DataHolder 对象。DataHolder 类封装了一个整数数组,并提供了设置数组值(setValue())和检索数组值(getValue())的方法。

在每个线程的 run() 方法中,一个 synchronized 块确保一次只有一个线程可以访问共享的 DataHolder 对象。线程递增一个值,使用 setValue() 将其设置在 DataHolder 中,并执行一些处理。当值达到 2 时,线程使用已弃用的 suspend() 方法挂起自身,这可能导致死锁场景。

主线程启动 thread1 和 thread2,然后并发执行其操作。代码片段作为示例,用于演示使用 suspend() 等已弃用方法可能带来的问题和危险。

需要注意的是,出于潜在死锁和线程安全违规等固有风险的考虑,不鼓励使用 suspend() 和 resume() 方法进行线程同步。现代并发机制,如锁、信号量和条件变量,提供了更安全的管理线程同步和通信的替代方案。