本文讲解了 Java 中线程中断的语法和应用场景,并给出了样例代码。线程中断指的是一个线程发送一个中断信号给另一个线程,通知其应该中断当前的执行。
jvm.cpp中调用了Thread::interrupt,回到thread.hpp源码的源码:
在之前的一文《如何"优雅"地终止一个线程》中详细说明了 stop 终止线程的坏处及如何优雅地终止线程,那么还有别的可以终止线程的方法吗?答案是肯定的,它就是我们今天要分享的——线程中断。
有线程运行,肯定就会有线程中断,在Java语言中,线程中断是一种协作机制,通过对线程设置中断标记,告知对应的线程,根据中断标记来决定是否需要中断当前线程。也就是说,在线程运行过程中,其实我们没有办法安全,准确的终止一个线程。
线程中断 线程中断即线程运行过程中被其他线程给打断了,它与 stop 最大的区别是:stop 是由系统强制终止线程,而线程中断则是给目标线程发送一个中断信号 如果目标线程没有接收线程中断的信号并结束线程,线程则不会终止,具体是否退出或者执行其他逻辑由目标线程决定 例1 中断失败 package com.starry.codeview.threads.P05_ThreadInterrupt; /** * 线程中断失败, 因为目标线程收到中断信号并没有做出处理 */ public class T01_Th
下面的这断代码大家应该再熟悉不过了,线程休眠需要捕获或者抛出线程中断异常,也就是你在睡觉的时候突然有个人冲进来把你吵醒了。
线程中断是线程的标志位属性。而不是真正终止线程,和线程的状态无关。线程中断过程表示一个运行中的线程,通过其他线程调用了该线程的 interrupt() 方法,使得该线程中断标志位属性改变。
经过上几篇博文的学习,我们知道在Java中可以通过new Thread().start()创建一个线程,那今天我们就来思考另外一个问题:线程的终止自然终止有两种情况:
在Java程序中,我们想要停止一个线程可以通过interrupt方法进行停止。但是当我们调用interrupt方法之后,它可能并不会立刻就会停止线程,而是通知线程需要停止。线程接收到通知之后会根据自身的情况判断是否需要停止,它可能会立即停止,也有可能会执行一段时间后停止,也可能根本就不停止。
我们一般都说这个方法是用来中断线程的,那么这个中断应该怎么理解呢?就是说把当前正在执行的线程中断掉,不让它继续往下执行吗?
“ 在前面分析Condition的时候,被阻塞的线程在我关闭应用的时候,会抛出异常,这是因为阻塞的线程被其他线程中断了。其实在学习AQS的时候我们也说过线程中断,AQS中acquire方法会忽略线程中断。现在我们来了解一下什么叫线程中断”
何谓优雅退出线程,即业务将进行中请求正确被处理,取消待执行请求,执行资源回收,最终Thread Runable run 方法return 结束执行。
如果代码能够在某个操作正常完全之前置入“完成”状态,那么这个操作就称为可取消的。java中提供了协作式机制,使请求取消的任务和代码遵循一种协商好的协议。
对线程调用interrupt方法,线程中断状态将被置位(线程总会不断的检验这个标志,判断线程是否被中断),想要知道线程是否被置位,就要调用静态的方法
一个位5年的小伙伴去某东面试被一道并发编程的面试题给Pass了,说”如何中断一个正在运行中的线程?,这个问题很多工作2年的都知道,实在是有些遗憾。
一般情况下,线程执行完成后就会结束,但有的时候我们可能需要在它正常执行完成前就停止它,可以考虑使用以下三种方法:
在Java中没有一种安全的抢占式方法来停止线程任务。只有一些协作式的机制,使请求取消的任务和代码都遵循一种协商好的协议。
线程中断并不会使线程立即退出,而是给线程发送一个通知,告知目标线程,有人希望你退出了!至于目标线程接收到通知之后如何处理,则完全由目标线程自己决定
通过上一篇《Java 并发(2)AbstractQueuedSynchronizer 源码分析之独占模式》的分析,我们知道了独占模式获取锁有三种方式,分别是不响应线程中断获取,响应线程中断获取,设置超时时间获取。在共享模式下获取锁的方式也是这三种,而且基本上都是大同小异,我们搞清楚了一种就能很快的理解其他的方式。
https://github.com/FutaoSmile/learn-thread/tree/master/src/main/java/com/futao/learn/threads/c_%E5%A6%82%E4%BD%95%E5%81%9C%E6%AD%A2%E7%BA%BF%E7%A8%8B
前面的几篇文章主要介绍了线程的一些最基本的概念,包括线程的间的冲突及其解决办法,以及线程间的协作机制。本篇主要来学习下Java中对线程中断机制的实现。在我们的程序中经常会有一些不达到目的不会
这3个方法都是用于线程中断操作或判断的。那么,严格地讲,线程中断并不会是线程立即退出,而是给线程发送一个通知,告知目标线程有人希望你退出了,至于目标线程接到通知后如何处理,则完全由目标线程自行决定。 三个方法的区别: interrupt():中断线程,并添加中断状态。 interrupted():判断是否被中断,并清除当前中断状态。 isInterrupted():只是判断是否被中断,并不清除当前中断状态。 实例一:我们利用interrupt()来打断线程 实例二:利用interrupted()清除中断
线程中断可能在平时的开发中我们用的不多,但是我相信大部分都见过InterruptedException,因为不管我们在调用object.wait()还是Thread.sleep()都会抛出一个InterruptedException。可能有很多人都是直接的继续抛出去或者不做任何处理直接打印堆栈信息,当然有可能这样没有问题,但是有些业务我们这样处理并不适合。要弄懂这些,我们就需要知道interrupt的作用是什么。
对于很多刚接触编程的人来说,对于线程中断和线程阻塞两个概念,经常性是混淆起来用,单纯地认为线程中断与线程阻塞的概念是一致的,都是值线程运行状态的停止。其实这个观点是错误的,两者之前有很大的区别,下文就着重介绍两者之间的区别。
在上一篇《Java 并发系列(1)AbstractQueuedSynchronizer 源码分析之概要分析》中介绍了 AbstractQueuedSynchronizer 基本的一些概念,主要讲了 AQS 的排队区是怎样实现的,什么是独占模式和共享模式以及如何理解结点的等待状态。理解并掌握这些内容是后续阅读 AQS 源码的关键,所以建议读者先看完我的上一篇文章再回过头来看这篇就比较容易理解。
在平时的开发过程中,相信都会使用到多线程,在使用多线程时,大家也会遇到各种各样的问题,今天我们就来说说一个多线程的问题——线程中断。在java中启动线程非常容易,大多数情况下我是让一个线程执行完自己的任务然后自己停掉,但是有时候我们需要取消某个操作,比如你在网络下载时,有时候需要取消下载。实现线程的安全中断并不是一件容易的事情,因为Java并不支持安全快速中断线程的机制,这里估计很多同学就会说了,java不是提供了Thread.interrupt 方法中断线程吗,好吧,我们今天就从这个方法开始说起。
interrupt()是用于中断线程的,调用该方法的线程的状态将被置为"中断"状态。注意:线程中断仅仅是设置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态为并做处理。这里可以看到中断后该线程还在继续往下执行,并没有强制终止线程。
在服务化系统中,对于上下游服务的依赖调用往往是通过RPC接口调用实现的,为了系统稳定性,防止被上游服务超时hang死,我们需要对接口调用设置超时,如果在设置的超时时间内没有响应,则需要提早中断该请求并返回。
通过前面三篇的分析,我们深入了解了 AbstractQueuedSynchronizer 的内部结构和一些设计理念,知道了 AbstractQueuedSynchronizer 内部维护了一个同步状态和两个排队区,这两个排队区分别是同步队列和条件队列。
首先,一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止,自己来决定自己的命运。所以,Thread.stop, Thread.suspend, Thread.resume 都已经被废弃了。
-- 1. 继承 Thread 运行线程 : 重写 Thread 类的 run 方法, 然后执行该线程;
之前发过,但是因为之前忘记标记原创,没办法收录在【并发编程专题】里面,作为强迫症的我,必须要重发一次。本文为第 11 篇,前面几篇没看过的,可以在文末找到前几篇的跳转链接。本文介绍线程调度的如下几个操作:
在Core Java中有这样一句话:"没有任何语言方面的需求要求一个被中断的程序应该终止。中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断 " 线程中断不会使线程立即退出,而是给线程发送一个通知,告知目标线程有人希望你退出。至于目标线程接收到通知后如何处理,则完全由目标线程自行决定。
处于NEW状态的线程此时尚未启动。这里的尚未启动指的是还没调用Thread实例的start()方法。
上面的定义很完整,对进程进行了全方面的定义,但是貌似进程是看不见摸不着的一个东西,实际上,我们可以通过查看计算机的进程管理器来查看应用程序的进程。
我们在进行开发的过程中。往往会由于各种需求会需要控制后台协程的细粒度。比如,界面关闭了。那么在这个界面中启动的协程已经不需要再执行了。
如果线程池线程数量太小,当有大量请求需要处理,系统响应比较慢,会影响用户体验,甚至会出现任务队列大量堆积任务导致OOM。
安全点(safepoint): JVM并不是为每条指令都生成OopMap,当JVM进入特定的位置,记录的信息才能进能暂停用户线程进入GC流程,这个点称为安全点。
上周写了一篇多线程的文章,其实更多方面是偏基础一点的文章,而且也比较大白话,争取人人都能看的明白,再举一些常见的例子,能很好的帮助大家理解多线程,文章发表之后我投给了几个大号和CSDN反应都挺好的,大家表示希望能写更多这样的文章,希望再多写写线程相关的文章,所以我打算从线程的基础开始写起,每周写那么两三篇,大家闲的时候可以看看,也可以多吸收一点东西。
一种常用的方法是在任务代码中加入一个“是否取消”的标志,任务定期去查看这个标志是否改变,如果被改变了就取消剩下的任务,此时如果想取消这个任务只需要修改它的标志,然后安静地等待其退出即可。
" LockSupport 是 JUC 中常用的一个工具类,主要作用是挂起和唤醒线程。在阅读 JUC 源码中经常看到,所以很有必要了解一下。下面会介绍源码中的注释,以及一步一步用代码去验证一些猜想。"
一行一行源码分析清楚 AbstractQueuedSynchronizer (二)
前言 昨天已经写了: 多线程三分钟就可以入个门了! 如果没看的同学建议先去阅读一遍哦~ 在写文章之前通读了一遍《Java 核心技术 卷一》的并发章节和《Java并发编程实战》前面的部分,回顾了一下以前写过的笔记。从今天开始进入多线程的知识点咯~ 我其实也是相当于从零开始学多线程的,如果文章有错的地方还请大家多多包含,不吝在评论区下指正呢~~ 一、Thread线程类API 声明本文使用的是JDK1.8 实现多线程从本质上都是由Thread类来进行操作的~我们来看看Thread类一些重要的知识点。Thread这
1.java.util.concurrent包中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列、条件队列、独占获取、共享获取等,而这些行为的抽象就是基于AbstractQueuedSynchronizer(简称AQS)实现的,AQS是一个抽象同步框架,可以用来实现一个依赖状态的同步器。
在jdk1.0时代,要终止一个Java线程,可以使用Thread提供的stop()和destroy()等方法,但这些方法在jdk1.4之后就已经不推荐使用了,原因是这些方法会强行关闭当前线程,并解锁当前线程已经持有的所有监视器(互斥锁、共享锁),这会导致被这些监视器保护的数据对象处于不一致的状态,其它线程可以查看到这些不一致状态的数据对象,从而导致各种不可预知的错误。
就像我们每天去到公司一样,先打开电脑,在电脑开机过程中可以去接点水喝,而不用等待电脑开机再去接水喝。
领取专属 10元无门槛券
手把手带您无忧上云