为什么不推荐使用 stop、suspend 方法中断线程,Java知识点思维导图

                  System.out.println("t1结束");

              } catch (InterruptedException e) {

                  e.printStackTrace();

              }

          }

    });

    t1.start();

    Thread.sleep(1000);

    Thread t2=new Thread(()->{

        synchronized (o1)

        {

            try {

                System.out.println("t2获取到锁");

                Thread.sleep(5000);//执行业务逻辑

                System.out.println("t2结束");

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

    });

    t2.start();

    flag=true;

}

复制代码




运行结果:



![](https://img-blog.csdnimg.cn/img_convert/1106622945c20bcb8c1e1979027d59c6.webp?x-oss-process=image/format,png)



**2.使用interrupt方法中断线程。**



代码举例如下:



public static void main(String[] args) throws InterruptedException {

    Object o1=new Object();

    Thread t1=new Thread(()->{

          synchronized (o1)

          {

              System.out.println("t1获取到锁");

              while (!Thread.currentThread().isInterrupted()) {

                  for (int i = 0; i < 100; i++) {

                      if(i==50)

                          System.out.println();

                      System.out.print(i+" ");

                  }

                  System.out.println();

              }

              System.out.println("t1结束");

          }

    });

    t1.start();

    Thread t2=new Thread(()->{

        synchronized (o1)

        {

            try {

                System.out.println("t2获取到锁");

                Thread.sleep(5000);//执行业务逻辑

                System.out.println("t2结束");

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

    });

    t2.start();

    t1.interrupt();

}

复制代码




运行结果:



![](https://img-blog.csdnimg.cn/img_convert/6d4a2a3a8ff9ab2449ee92352804a494.webp?x-oss-process=image/format,png)



我们用while (!Thread.currentThread().isInterrupted())来不断判断当前线程是否被中断,中断的话则让线程自然消亡并释放锁。可以看到调用interrupt方法后并不会像stop那样暴力的中断线程,会等到当前运行的逻辑结束后再检查是否中断,非常的优雅。



> 注:运行举例代码可能不会打印出数字,这是因为t1线程运行到while(!Thread.currentThread().isInterrupted())时,主线程已经调了interrupt方法,因此多次运行可能会打印出数字。



**二、suspend的落幕**

----------------



suspend方法的作用是挂起某个线程直到调用resume方法来恢复该线程,但是调用了suspend方法后并不会释放被挂起线程获取到的锁,正因如此就给suspend和resume这哥俩贴上了容易引发死锁的标签,当然这也正是导致suspend和resume退出历史舞台的罪魁祸首。同样我们看看java开发者为suspend的淘汰给出的理由:



> This method has been deprecated, as it is inherently deadlock-prone. If the target thread holds a lock on the monitor protecting a critical system resource when it is suspended, no thread can access this resource until the target thread is resumed. If the thread that would resume the target thread attempts to lock this monitor prior to calling resume, deadlock results. Such deadlocks typically manifest themselves as “frozen” processes.



从中我们可以得出以下结论:



1.  suspend具有天然的死锁倾向

2.  当某个线程被suspend后,该线程持有的锁不会被释放,其他线程也就不能访问这些资源

3.  suspend某个线程后,如果在resume的过程中出现异常导致resume方法执行失败,则lock无法释放,导致死锁



接下来模拟一下由suspend引起的死锁场景,Talk is cheap,show my code:



public static void main(String[] args) throws InterruptedException {

    Object o1=new Object();

    Object o2=new Object();

    Thread t1=new Thread(()->{

          synchronized (o1)

          {

              System.out.println("t1获取到o1锁开始执行");

              try {

                  Thread.sleep(5000);//模拟执行业务逻辑

              } catch (InterruptedException e) {

                  e.printStackTrace();

              }

              System.out.println("t1执行结束");

          }

    });

    t1.start();

    Thread t2=new Thread(()->{

        synchronized (o2)

        {

            System.out.println("t2获取到o2开始执行");

            try {

                Thread.sleep(2000);//执行耗时业务

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            synchronized (o1)

            {

                System.out.println("t2获取到o1锁开始继续执行");

            }

            System.out.println("t2执行结束");

        }

    });

    t2.start();



    Thread.sleep(1000);

    t1.suspend();

    //假设抛出了一个未知异常

    int i=1/0;

    t1.resume();

}

复制代码




运行结果:



![](https://img-blog.csdnimg.cn/img_convert/66acf703b7654a7aaaf9625cc3141905.webp?x-oss-process=image/format,png)



可以看到,整个程序卡的死死的,在调用resume恢复t1线程之前抛出了一个未知异常,导致t1一直挂起进而无法释放o1锁,而t2需要获取到o1锁后才能继续执行,但苦苦等待,奈何o1被t1拿捏的死死的,从此整个程序就陷入了无尽的等待中----死锁。


## 最后

**码字不易,觉得有帮助的可以帮忙点个赞,让更多有需要的人看到**

又是一年求职季,在这里,我为各位准备了一套Java程序员精选高频面试笔试真题,来帮助大家攻下BAT的offer,题目范围从初级的Java基础到高级的分布式架构等等一系列的面试题和答案,用于给大家作为参考

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](https://codechina.csdn.net/m0_60958482/java-p7)**

以下是部分内容截图
的死死的,从此整个程序就陷入了无尽的等待中----死锁。


## 最后

**码字不易,觉得有帮助的可以帮忙点个赞,让更多有需要的人看到**

又是一年求职季,在这里,我为各位准备了一套Java程序员精选高频面试笔试真题,来帮助大家攻下BAT的offer,题目范围从初级的Java基础到高级的分布式架构等等一系列的面试题和答案,用于给大家作为参考

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](https://codechina.csdn.net/m0_60958482/java-p7)**

以下是部分内容截图
![架构面试专题及架构学习笔记导图.png](https://img-blog.csdnimg.cn/img_convert/6dbbf91a4f8248435183c221a03c2137.png)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值