线程 - 这段危险代码90%的人都写过!

简介: 线程 - 这段危险代码90%的人都写过!

最近一个同学发来消息说,公司里有一段代码使用的线程经常会发生一些莫名其妙的问题。让我帮忙看看,我仔细看了很多遍线程的相关代码。最后注意到了 InterruptException 异常,把想法和 demo 代码给他说了后,问题果真被解决了。


关于这个问题,我通过一段简化的代码来给大家演示一下。



image.png



看到上面这段 demo 了吗?多简单,多熟悉啊。但是有一个问题,90% 的人可能都没有遇到,但确实存在的。


我们先看 Thread.sleep 为什么要抛出一个异常?其实,很简单,你仔细想想,如果你正在睡觉的时候,突然有人打扰到你,是不是就相当于发生了中断睡觉的异常。而 InterruptedException 这个异常的发生就是因为有人打扰了这个线程的休眠。


谁打扰的呢?就是调用这个线程的 interrupt() 方法的对象。OK ,现在我们来看看,当我调用上面这个线程的 interrupt() 方法的时候,它正在休眠,那么就会发生 InterruptedException 异常。而这个时候,你却把 InterruptedException 异常捕捉了,于是本该停止的线程就行失去刹车的车辆一样裸奔了。


而正确的处理 InterruptedException 异常的方法是,捕捉异常之后,加一个 break,终止线程。除此之外,结束一个线程推荐的方法有 3 种。



image.png


现在我们再来看看为什么 Thread.stop、Thread.suspend、Thread.resume、Runtime.runFinalizersOnExit 这几个方法都被废弃了。这是因为,这几个操作太暴力了。stop() 方法会真的杀死线程,不给线程喘息的机会,如果线程持有 ReentrantLock 锁,被 stop() 的线程并不会自动调用 ReentrantLock 的 unlock() 去释放锁,那其他线程就再也没机会获得 ReentrantLock 锁,这实在是太危险了。所以该方法就不建议使用了,类似的方法还有 suspend() 和 resume() 方法、Runtime.runFinalizersOnExit() 方法,这 3 个方法同样也都不建议使用了。危害性都非常大,所以被废弃的方法你千万不要使用!


目录
相关文章
|
6月前
多线程案例-定时器(附完整代码)
多线程案例-定时器(附完整代码)
296 0
|
6月前
|
数据采集 Python
【Python自动化】多线程BFS站点结构爬虫代码,支持中断恢复,带注释
【Python自动化】多线程BFS站点结构爬虫代码,支持中断恢复,带注释
68 0
|
6月前
|
Java
|
4月前
|
安全 Python
告别低效编程!Python线程与进程并发技术详解,让你的代码飞起来!
【7月更文挑战第9天】Python并发编程提升效率:**理解并发与并行,线程借助`threading`模块处理IO密集型任务,受限于GIL;进程用`multiprocessing`实现并行,绕过GIL限制。示例展示线程和进程创建及同步。选择合适模型,注意线程安全,利用多核,优化性能,实现高效并发编程。
69 3
|
6月前
|
设计模式 监控 Java
Java多线程基础-11:工厂模式及代码案例之线程池(一)
本文介绍了Java并发框架中的线程池工具,特别是`java.util.concurrent`包中的`Executors`和`ThreadPoolExecutor`类。线程池通过预先创建并管理一组线程,可以提高多线程任务的效率和响应速度,减少线程创建和销毁的开销。
186 2
|
6月前
|
安全 Java
Java多线程基础-10:代码案例之定时器(一)
`Timer` 是 Java 中的一个定时器类,用于在指定延迟后执行指定的任务。它常用于实现定时任务,例如在网络通信中设置超时或定期清理数据。`Timer` 的核心方法是 `schedule()`,它可以安排任务在延迟一段时间后执行。`
129 1
|
3月前
|
Java Windows
【Azure Developer】Windows中通过pslist命令查看到Java进程和线程信息,但为什么和代码中打印出来的进程号不一致呢?
【Azure Developer】Windows中通过pslist命令查看到Java进程和线程信息,但为什么和代码中打印出来的进程号不一致呢?
|
3月前
|
Java 开发者
解锁Java并发编程的秘密武器!揭秘AQS,让你的代码从此告别‘锁’事烦恼,多线程同步不再是梦!
【8月更文挑战第25天】AbstractQueuedSynchronizer(AQS)是Java并发包中的核心组件,作为多种同步工具类(如ReentrantLock和CountDownLatch等)的基础。AQS通过维护一个表示同步状态的`state`变量和一个FIFO线程等待队列,提供了一种高效灵活的同步机制。它支持独占式和共享式两种资源访问模式。内部使用CLH锁队列管理等待线程,当线程尝试获取已持有的锁时,会被放入队列并阻塞,直至锁被释放。AQS的巧妙设计极大地丰富了Java并发编程的能力。
41 0
|
5月前
|
API
linux---线程互斥锁总结及代码实现
linux---线程互斥锁总结及代码实现
|
5月前
|
Java
【代码诗人】Java线程的生与死:一首关于生命周期的赞歌!
【6月更文挑战第19天】Java线程生命周期,如诗般描绘了从新建到死亡的旅程:创建后待命,`start()`使其就绪,获得CPU则运行,等待资源则阻塞,任务完或中断即死亡。理解生命周期,善用锁、线程池,优雅处理异常,确保程序高效稳定。线程管理,既是艺术,也是技术。
29 3