iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > VUE >如何理解线程中断的问题
  • 418
分享到

如何理解线程中断的问题

2024-04-02 19:04:59 418人浏览 独家记忆
摘要

本篇内容主要讲解“如何理解线程中断的问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何理解线程中断的问题”吧!实现线程本质上只有一种方式为什么不强制停止对于

本篇内容主要讲解“如何理解线程中断的问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何理解线程中断的问题”吧!

实现线程本质上只有一种方式

为什么不强制停止

对于 Java 而言,最正确的停止线程的方式是使用 interrupt。但  interrupt仅仅起到通知被停止线程的作用。而对于被停止的线程而言,它拥有完全的自主权,它既可以选择立即停止,也可以选择一段时间后停止,也可以选择压根不停止。

为什么 Java 不提供强制停止线程的能力呢?事实上,Java  希望程序间能够相互通知、相互协作地管理线程,因为如果不了解对方正在做的工作,贸然强制停止线程就可能会造成一些安全的问题。

比如:线程正在写入一个文件,这时收到终止信号,它就需要根据自身业务判断,是选择立即停止,还是将整个文件写入成功后停止。如果选择立即停止就可能造成数据不完整,不管是中断命令发起者,还是接收者都不希望数据出现问题。

如何用 interrupt 停止线程

while (!Thread.currentThread().isInterrupted()  && more work to do) {     do more work }

我们一旦调用某个线程的 interrupt()  之后,这个线程的中断标记位就会被设置成true。每个线程都有这样的标记位,当线程执行时,应该定期检查这个标记位,如果标记位被设置成  true,就说明有程序想终止该线程。

回到源码,可以看到在 while 循环体判断语句中,首先通过

Thread.currentThread().isInterrupt()

判断线程是否被中断,随后检查是否还有工作要做。&& 逻辑表示只有当两个判断条件同时满足的情况下,才会去执行下面的工作。

public class StopThread implements Runnable {       @Override     public void run() {         int count = 0;         while (!Thread.currentThread().isInterrupted() && count < 1000) {             System.out.println("count = " + count++);         }     }       public static void main(String[] args) throws InterruptedException {         Thread thread = new Thread(new StopThread());         thread.start();         Thread.sleep(5);         thread.interrupt();     } }

在 StopThread 类的 run() 方法中,首先判断线程是否被中断,然后判断 count 值是否小于 1000。

这个线程的工作内容很简单,就是打印 0~999 的数字,每打印一个数字 count 值加  1,可以看到,线程会在每次循环开始之前,检查是否被中断了。接下来在 main 函数中会启动该线程,然后休眠 5  毫秒后立刻中断线程,该线程会检测到中断信号,于是在还没打印完1000个数的时候就会停下来,这种就属于通过 interrupt 正确停止线程的情况。

sleep 期间能否感受到中断

先说结论,可以。

public class StopDuringSleep {       public static void main(String[] args) throws InterruptedException {         Runnable runnable = () -> {             int num = 0;             try {                 while (!Thread.currentThread().isInterrupted() && num <= 1000) {                     System.out.println(num);                     num++;                     Thread.sleep(1000000);                 }             } catch (InterruptedException e) {                 e.printStackTrace();             }         };         Thread thread = new Thread(runnable);         thread.start();         Thread.sleep(5);         thread.interrupt();     } }

运行后的结果你猜怎么着,程序会抛出异常

如何理解线程中断的问题

如果 sleep、wait  等可以让线程进入阻塞的方法使线程休眠了,而处于休眠中的线程被中断,那么线程是可以感受到中断信号的,并且会抛出一个 InterruptedException  异常,同时清除中断信号,将中断标记位设置成  false。这样一来就不用担心长时间休眠中线程感受不到中断了,因为即便线程还在休眠,仍然能够响应中断通知,并抛出异常。

但是这样只能相应一次中断信号了,怎么办?我的业务还没有完成收尾,怎么办?

合理利用好 try/catch

我们在实际开发中不能盲目吞掉中断,如果不在方法签名中声明,也不在 catch 语句块中再次恢复中断,而是在 catch  中不作处理,我们称这种行为是“屏蔽了中断请求”。如果我们盲目地屏蔽了中断请求,会导致中断信号被完全忽略,最终导致线程无法正确停止。

try {         Thread.sleep(2000);     } catch (InterruptedException e) { //        此处处理中断异常请求,业务收尾     }

停止线程的方式有几种

void shutdown; boolean isshutdown; boolean isTerminated; boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException; List<Runnable> shutdownNow;

下面我们就对这些方法逐一展开。

shutdown()

调用 shutdown() 方法之后线程池并不是立刻就被关闭,因为这时线程池中可能还有很多任务正在被执行,或是任务队列中有大量正在等待被执行的任务,调用  shutdown() 方法后线程池会在执行完正在执行的任务和队列中等待的任务后才彻底关闭。但这并不代表 shutdown() 操作是没有任何效果的,调用  shutdown() 方法后如果还有新的任务被提交,线程池则会根据拒绝策略直接拒绝后续新提交的任务。

isShutdown()

它可以返回 true 或者 false 来判断线程池是否已经开始了关闭工作,也就是是否执行了 shutdown 或者 shutdownNow  方法。这里需要注意,如果调用 isShutdown() 方法的返回的结果为 true  并不代表线程池此时已经彻底关闭了,这仅仅代表线程池开始了关闭的流程,也就是说,此时可能线程池中依然有线程在执行任务,队列里也可能有等待被执行的任务。

isTerminated()

这个方法可以检测线程池是否真正“终结”了,这不仅代表线程池已关闭,同时代表线程池中的所有任务都已经都执行完毕了,因为我们刚才说过,调用 shutdown  方法之后,线程池会继续执行里面未完成的任务,不仅包括线程正在执行的任务,还包括正在任务队列中等待的任务。比如此时已经调用了 shutdown  方法,但是有一个线程依然在执行任务,那么此时调用 isShutdown 方法返回的是 true ,而调用 isTerminated 方法返回的便是 false  ,因为线程池中还有任务正在在被执行,线程池并没有真正“终结”。直到所有任务都执行完毕了,调用 isTerminated() 方法才会返回  true,这表示线程池已关闭并且线程池内部是空的,所有剩余的任务都执行完毕了。

awaitTermination()

第四个方法叫作 awaitTermination(),它本身并不是用来关闭线程池的,而是主要用来判断线程池状态的。比如我们给  awaitTermination 方法传入的参数是 10 秒,那么它就会陷入 10 秒钟的等待,直到发生以下三种情况之一:

  • 等待期间(包括进入等待状态之前)线程池已关闭并且所有已提交的任务(包括正在执行的和队列中等待的都执行完毕,相当于线程池已经“终结”了,方法便会返回true

  • 等待超时时间到后,第一种线程池“终结”的情况始终未发生,方法返回 false

  • 等待期间线程被中断,方法会抛出 Interruptedexception异常

等待期间(包括进入等待状态之前)线程池已关闭并且所有已提交的任务(包括正在执行的和队列中等待的)都执行完毕,相当于线程池已经“终结”了,方法便会返回  true;

等待超时时间到后,第一种线程池“终结”的情况始终未发生,方法返回 false;等待期间线程被中断,方法会抛出 InterruptedException  异常。

shutdownNow()

最后一个方法是 shutdownNow(),也是 5 种方法里功能最强大的,它与第一种 shutdown 方法不同之处在于名字中多了一个单词  Now,也就是表示立刻关闭的意思。在执行 shutdownNow 方法之后,首先会给所有线程池中的线程发送 interrupt  中断信号,尝试中断这些任务的执行,然后会将任务队列中正在等待的所有任务转移到一个 List 中并返回,我们可以根据返回的任务 List  来进行一些补救的操作,例如记录在案并在后期重试。

public List<Runnable> shutdownNow() {      List<Runnable> tasks;     final ReentrantLock mainLock = this.mainLock;     mainLock.lock();      try {          checkShutdownAccess();         advanceRunState(STOP);         interruptWorkers();         tasks = drainQueue();     } finally {          mainLock.unlock();     }        tryTerminate();     return tasks;  }

源码中有一行 interruptWorkers()  代码,这行代码会让每一个已经启动的线程都中断,这样线程就可以在执行任务期间检测到中断信号并进行相应的处理,提前结束任务。这里需要注意的是,由于 Java  中不推荐强行停止线程的机制的限制,即便我们调用了 shutdownNow 方法,如果被中断的线程对于中断信号不理不睬,那么依然有可能导致任务不会停止。

到此,相信大家对“如何理解线程中断的问题”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: 如何理解线程中断的问题

本文链接: https://www.lsjlt.com/news/84038.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何理解线程中断的问题
    本篇内容主要讲解“如何理解线程中断的问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何理解线程中断的问题”吧!实现线程本质上只有一种方式为什么不强制停止对于...
    99+
    2022-10-19
  • Java中线程安全问题该如何理解
    这期内容当中小编将会给大家带来有关Java中线程安全问题该如何理解,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。线程安全问题是一个比较高深的问题,是很多程序员比较难掌握的一个技术难点,如果一个程序员对线程...
    99+
    2023-06-17
  • 如何解决Java中SimpleDateFormat线程不安全的问题
    这篇文章将为大家详细讲解有关如何解决Java中SimpleDateFormat线程不安全的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.什么是线程不安全?线程不安全也叫非线程安全,是指多线程执行中...
    99+
    2023-06-15
  • Java项目中的线程安全问题如何解决
    这篇文章给大家介绍Java项目中的线程安全问题如何解决,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。解决方案如下:public class Demo_5 { public&nbs...
    99+
    2023-05-31
    java 线程安全 ava
  • 如何解析Java线程池在使用中的问题
    本篇文章为大家展示了如何解析Java线程池在使用中的问题,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Java线程池需要我们不断的学习,其实我们在使用的时候还是有不少问题需要我们解决。我们实现了一个...
    99+
    2023-06-17
  • PHP如何解决swoole守护进程Redis假死 ,mysql断线重连问题?
    PHP如何解决swoole守护进程Redis假死 ,mysql断线重连问题? 最近公司有个项目,要举办一个线上活动,我这边负责提供接口记录用户访问记录,与操作记录,由于活动参与人数可能比较多...
    99+
    2023-09-03
    php swoole redis
  • 怎么解决oracle在线创建索引中断问题
    本篇内容主要讲解“怎么解决oracle在线创建索引中断问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么解决oracle在线创建索引中断问题”吧!进行在线创...
    99+
    2022-10-18
  • C++中的多线程同步问题详解
    C++中的多线程同步问题详解在并发编程中,多线程同步是一个重要的问题。当多个线程同时访问共享资源时,会引发各种问题,如竞态条件(Race Condition)、死锁(Deadlock)和活锁(Livock),这些问题都会导致程序的不确定性和...
    99+
    2023-10-22
    C++ 多线程 同步问题
  • redis单线程并发问题如何解决
    Redis是一个单线程的内存数据库,它使用了事件驱动的模型,通过将请求放入一个队列中顺序执行来实现并发处理。但是,在高并发情况下,可...
    99+
    2023-09-11
    redis
  • java多线程并发问题如何解决
    在Java中,可以使用以下方法来解决多线程并发问题:1. 使用synchronized关键字:可以通过在方法或代码块前加上synch...
    99+
    2023-09-27
    java
  • 如何解决Java多线程死锁问题
    死锁问题 死锁定义 多线程编程中,因为抢占资源造成了线程无限等待的情况,此情况称为死锁。 死锁举例 注意:线程和锁的关系是:一个线程可以拥有多把锁,一个锁只能被一个线程拥有。 当两个...
    99+
    2022-11-12
  • Android中的多线程问题
    目录一:问题的提出二:使用Handler处理多线程问题三:使用AsyncTask(异步任务)处理多线程问题 一:问题的提出 Android用户界...
    99+
    2022-06-06
    多线程 线程 Android
  • 如何解决Win7下ADSL自动断线的问题方法是什么
    Windows7下ADSL自动断线的问题及解决方法 在 Windows7 中,为什么 ADSL 闲置一段时间就会自动断线呢?在其它软硬件工作正常的情况下,出现这种问题,多半是因为启...
    99+
    2023-05-25
    ADSL Win7 问题 方法
  • 如何解决MySQL线程处于Opening tables的问题
    这篇文章主要介绍了如何解决MySQL线程处于Opening tables的问题,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。本篇文章给大家带来的...
    99+
    2022-10-18
  • C++多线程编程中的并发问题解析
    C++多线程编程中的并发问题解析随着计算机硬件的不断发展,多核处理器已经成为了主流。在这种情况下,使用多线程来充分利用多核处理器的性能,成为了程序开发中的一项重要技术。然而,在多线程编程中,由于多个线程之间的并发操作,常常会导致一些问题,这...
    99+
    2023-10-22
    解析 并发问题 C++多线程编程
  • Struts中action线程安全问题解析
    【问题描述】最近公司安排我面试Java的FreshMan,面试者一般是工作1年多点的新人(这里我就装老一下,其实我也才工作3年不到),在被问及Struts1和Struts2的Action的线程安全问题的时候,大多是支支吾吾,答不出所以然。所...
    99+
    2023-05-30
    java action 线程安全
  • 如何解决mybatis的if判断integer问题
    这篇文章主要为大家展示了“如何解决mybatis的if判断integer问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何解决mybatis的if判断integer问题”这篇文章吧。if判断...
    99+
    2023-06-29
  • 如何处理PHP开发中的多线程和并发问题
    一、引言随着互联网的迅速发展,Web应用程序的性能和并发处理是一个至关重要的问题。特别是在PHP开发中,由于PHP是一种解释型语言,其自身的单线程特性导致其并发处理能力有限。然而,在某些场景下,我们仍然需要实现多线程和并发处理来提升Web应...
    99+
    2023-10-21
    PHP多线程 并发问题
  • 解决SpringBoot中的Scheduled单线程执行问题
    目录问题描述原因分析:解决方案:补充:问题描述 在一次SpringBoot中使用Scheduled定时任务时,发现某一个任务出现执行占用大量资源,会导致其他任务也执行失败。类似于以下...
    99+
    2022-11-13
  • Java中线程状态+线程安全问题+synchronized的用法详解
    目录java中的线程状态线程安全问题案例分析多线程对同一变量进行写操作内存可见性问题指令重排序问题synchronized的用法synchronized起作用的本质修饰普通方法修饰静...
    99+
    2022-11-13
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作