探究 JDK 源码中 stop()、suspend() 线程中断方法被淘汰的原因及替代方案!

最后

分享一套我整理的面试干货,这份文档结合了我多年的面试官经验,站在面试官的角度来告诉你,面试官提的那些问题他最想听到你给他的回答是什么,分享出来帮助那些对前途感到迷茫的朋友。

面试经验技巧篇
  • 经验技巧1 如何巧妙地回答面试官的问题
  • 经验技巧2 如何回答技术性的问题
  • 经验技巧3 如何回答非技术性问题
  • 经验技巧4 如何回答快速估算类问题
  • 经验技巧5 如何回答算法设计问题
  • 经验技巧6 如何回答系统设计题
  • 经验技巧7 如何解决求职中的时间冲突问题
  • 经验技巧8 如果面试问题曾经遇见过,是否要告知面试官
  • 经验技巧9 在被企业拒绝后是否可以再申请
  • 经验技巧10 如何应对自己不会回答的问题
  • 经验技巧11 如何应对面试官的“激将法”语言
  • 经验技巧12 如何处理与面试官持不同观点这个问题
  • 经验技巧13 什么是职场暗语

面试真题篇
  • 真题详解1 某知名互联网下载服务提供商软件工程师笔试题
  • 真题详解2 某知名社交平台软件工程师笔试题
  • 真题详解3 某知名安全软件服务提供商软件工程师笔试题
  • 真题详解4 某知名互联网金融企业软件工程师笔试题
  • 真题详解5 某知名搜索引擎提供商软件工程师笔试题
  • 真题详解6 某初创公司软件工程师笔试题
  • 真题详解7 某知名游戏软件开发公司软件工程师笔试题
  • 真题详解8 某知名电子商务公司软件工程师笔试题
  • 真题详解9 某顶级生活消费类网站软件工程师笔试题
  • 真题详解10 某知名门户网站软件工程师笔试题
  • 真题详解11 某知名互联网金融企业软件工程师笔试题
  • 真题详解12 国内某知名网络设备提供商软件工程师笔试题
  • 真题详解13 国内某顶级手机制造商软件工程师笔试题
  • 真题详解14 某顶级大数据综合服务提供商软件工程师笔试题
  • 真题详解15 某著名社交类上市公司软件工程师笔试题
  • 真题详解16 某知名互联网公司软件工程师笔试题
  • 真题详解17 某知名网络安全公司校园招聘技术类笔试题
  • 真题详解18 某知名互联网游戏公司校园招聘运维开发岗笔试题

资料整理不易,点个关注再走吧

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

可以看到java开发者推荐我们使用以下两种方法来优雅的停止线程。

1.定义一个变量,由目标线程去不断的检查变量的状态,当变量达到某个状态时停止线程。

代码举例如下:

volatile static boolean flag=false;

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

Object o1=new Object();

Thread t1=new Thread(()->{

synchronized (o1)

{

try {

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

while (!flag)

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

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;

}

运行结果:

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();

}

运行结果:

我们用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();

}

运行结果:

最后

金三银四到了,送上一个小福利!

image.png

image.png

专题+大厂.jpg

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

最后

金三银四到了,送上一个小福利!

[外链图片转存中…(img-uJN3APjz-1715545732004)]

[外链图片转存中…(img-gBNBLZCq-1715545732004)]

[外链图片转存中…(img-xiRkuqY4-1715545732004)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 25
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值