笔者在学习JUC包的时候,了解到同样用于线程阻塞和恢复功能的类—— LockSupport ,那么这个类和 Thread.suspend()Thread.resume() 有什么区别,为什么后者被弃用了?

阻塞小例子

该例子(来源于 Bug Database )很好的验证了 Thread.suspend()/resume() 这对兄弟天生容易犯错,在输出几个i之后就会发生永久性阻塞(通过jstack看,只能判断其是阻塞,无法判断是死锁):

  1. /* ---------Thread.suspend 和 resume发生“死锁”的示例--------- */
  2. public static void main(String[] args) throws InterruptedException {
  3. TestTask mainThread = new TestTask();
  4. mainThread.start();
  5. while(true){
  6. if(!mainThread.isTalking){
  7. // LockSupport.unpark(mainThread);
  8. mainThread.resume();
  9. mainThread.isTalking = true;
  10. }
  11. }
  12. }
  13. static class TestTask extends Thread {
  14. volatile boolean isTalking = true;
  15. int i = 0;
  16. public void run() {
  17. while (true) {
  18. if (isTalking) {
  19. i++;
  20. isTalking = false;
  21. // LockSupport.park();
  22. suspend();
  23. System.out.println(i);
  24. }
  25. }
  26. }
  27. }

弃用原因

在这个方面,笔者上网了解过很多,许多人都是泛泛而谈,甚至是随手复制粘贴,质量低的可怕,完全无法了解到为什么它被弃用了。笔者最后在 Bug Database 上了解到了原因:

Thread.suspend()Thread.resume() 发生阻塞的原因主要在于底层JVM在暂停时候的不安全,就算花大力气修复了 Thread.suspend()Thread.resume() ,问题也会转移到应用层级别(这一点暂时无法理解) 。

Thread.suspend() 和 Thread.resume() 被弃用的原因

有能力的朋友们可以直接看原文,可以一起交流一下看法。

替代方案

  1. Object.wait()Object.notify()/notifyAll() ,该方法需要在 synchronized 块中使用,极其麻烦
  2. LockSupport 粒度小,使用方便