2021-06-09 线程中断技术一览

背景

技术群里抛来一个问题:

如果我使用java多线程  同时执行两个线程  哪个线程先结束就使用哪个的结果  这个怎么实现

回答有几种:

Jobs Jia said:

两种方式,
1、线程里直接调你的后续流程,流程里做好幂等控制。
2、线程池返回 future,第一个get成功的 就执行,然后不等第二个

Wang 鹅 showed me the code:

image.png

Wang 鹅‘s brother Wang Happy agressed with him

你的思路是对的

But the questioner said nothing...

以上观点都OK。

说下我对这个问题的看法
作为一个后端老人,在线程协调之外,我想到的是任务设计的问题。
由于题目没有太多介绍,以下开始YY。

核心主旨是’哪个先结束,用哪个的结果‘。
那么,可见更看中性能。
任务无外乎两种,计算型、IO型
如果是IO型,放到2个线程里,不合适,意义也不大。
如果是简单计算型,DB操作这种,貌似没有太多讨论的意义,2个任务的处理时间,不会差太多。
以下主要讨论密集计算型,相应的,题目应该扩展一下,先执行完的线程提交结果,DoNext,而未执行完的线程应该尽快停止无谓的计算,减少不必要的资源浪费。

那么问题就涉及到了如果优雅有效的对线程进行中断。

打字好累,不扯了,直奔主题:Interrupt
Java的中断是一种协作机制,目的是做好任务的取消。

举个例子,本人觉得非常贴切。

岳飞抗金。
岳家军在行进途中,突然朝廷撤了他的职,也非不会立刻收到这个通知的,这个要发信到各级机构,信息传输也需要时间,等岳飞经过沿途的停靠点要进行短暂修整,才会收到通知,这时候岳飞要自己决定停止行动,并退出。
如果岳飞行进途中不停歇,他就不知道撤他职的信息。为啥朝廷没有直接通知他,因为没有了,好吧,我编不下去了。。。

中断相关的设计要点

线程执行的结果有两种

  1. 正常完成和结束
  2. 完成之前被终止

检查点

有两种方式,官方的是第一种

阻塞,被动中断

为啥Thread.sleep(1),会要求开发者catch一个InterruptedException呢,因为阻塞等待,可能会被打算。

JDK都有哪些阻塞点?
Thread.sleep()和Object.wait()
JUC和NIO部分类会有


image.png

轮询,主动查询

for(分批处理) {  //比如要对100W个向量进行计算,可以每批计算50个
  if(checkIsInturrepted()) {
    doNothing();
    return;
  }
  compute();
}

中断通知

中断的本质是通知
Thread.interrupt()到底做了啥,就是通知,写一个标志位,完了。


image.png

至于目标线程,要不要终止任务,外部无法干预。

中断响应

image.png

可以翻看JDK关于这方面的源码,会发现有大量这样的写法,是为了检测到终端操作,重置中断信号,不能吞掉,否则会影响其他组件的响应。

状态检查

Thread.currentThread().isInterrupted()

优雅停止

排水或者打个标

catch (InterruptedException ie) {
    interrupted = true;
}

向外通知

依托异常处理机制,继续抛,让上层知道

finally {
    if (interrupted)
        Thread.currentThread().interrupt();
}

结论:为响应中断而进行任务的设计
这是一种良好的编程习惯

未完待续。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容