有一个项目对实时性要求比较高,于是在linux内核上打了RT_PREEMPT补丁。
所谓实时,就是一个特定任务的执行时间必须是确定的,可预测的,并且在任何情况下都能保证任务的时限(最大执行时间限制)。实时又分软实时和硬实时,所谓软实时,就是对任务执行时限的要求不那么严苛,即使在一些情况下不能满足时限要求,也不会对系统本身产生致命影响,例如,媒体播放系统就是软实时的,它需要系统能够在1秒钟播放24帧,但是即使在一些严重负载的情况下不能在1秒钟内处理24帧,也是可以接受的。所谓硬实时,就是对任务的执行时限的要求非常严格,无论在什么情况下,任务的执行实现必须得到绝对保证,否则将产生灾难性后果,例如,飞行器自动驾驶和导航系统就是硬实时的,它必须要求系统能在限定的时限内完成特定的任务,否则将导致重大事故,如碰撞或爆炸等。
Ingo Molnar 的实时补丁是完全开源的,它采用的实时实现技术完全类似于Timesys Linux,而且中断线程化的代码是基于TimeSys Linux的中断线程化代码的。这些实时实现技术包括:中断线程化(包括IRQ和softirq)、用Mutex取代spinlock、优先级继承和死锁检测、等待队列优先级化等。
实时分为硬实时和软实时,硬实时要求绝对保证响应时间不超过期限,如果超过期限,会造成灾难性的后果,例如汽车在发生碰撞事故时必须快速展开安全气囊;软实时只需尽力使响应时间不超过期限,如果偶尔超过期限,不会造成灾难性的后果.
实时系统要求对事件的响应时间不能超过规定的期限,响应时间是指从某个事件发生到负责处理这个事件的进程处理完成的时间间隔,最大响应时间应该是确定的、可以预测的。
中断服务程序一般都是在中断请求关闭的条件下执行的,以避免嵌套而使中断控制复杂化。但是,中断是一个随机事件,它随时会到来,如果关中断的时间太长,CPU就不能及时响应其他的中断请求,从而造成中断的丢失。因此,Linux内核的目标就是尽可能快的处理完中断请求,尽其所能把更多的处理向后推迟。例如,假设一个数据块已经达到了网线,当中断控制器接受到这个中断请求信号时,Linux内核只是简单地标志数据到来了,然后让处理器恢复到它以前运行的状态,其余的处理稍后再进行(如把数据移入一个缓冲区,接受数据的进程就可以在缓冲区找到数据)。因此,内核把中断处理分为两部分:上半部(tophalf)和下半部(bottomhalf),上半部(就是中断服务程序)内核立即执行,而下半部(就是一些内核函数)留着稍后处理。
一般的linux都是GPOS(通用)内核。GPOS是不保证实时的,但是对于大多数应用程序来说是没有问题的。GPOS可以充分利用物理资源。但在实时性要求性比较高的场景需要使用实时内核,RT内核。RT的代价就是牺牲掉了资源利用率,使得相同的资源生产能力下降。
其中 stop 方法为 @Deprecated 修饰的过期方法,也就是不推荐使用的过期方法,因为 stop 方法会直接停止线程,这样就没有给线程足够的时间来处理停止前的保存工作,就会造成数据不完整的问题,因此不建议使用。而自定义中断标识也有一些问题,所以综合来看,interrupt 方法才是最理想的停止线程的方法,接下来我们一起来看它们的具体差异。
上周写了一篇多线程的文章,其实更多方面是偏基础一点的文章,而且也比较大白话,争取人人都能看的明白,再举一些常见的例子,能很好的帮助大家理解多线程,文章发表之后我投给了几个大号和CSDN反应都挺好的,大家表示希望能写更多这样的文章,希望再多写写线程相关的文章,所以我打算从线程的基础开始写起,每周写那么两三篇,大家闲的时候可以看看,也可以多吸收一点东西。
Linux内核的软中断("softirq")机制有些奇怪,在早期的Linux和处理机制下比较晦涩,且仅有极少的内核开发人员会直接接触软中断。然而它是内核的大多数重要处理的核心。在某些场景下,软中断会以一种不合时宜的方式出现。特别是内核的实时抢占补丁集经常会与软中断产生冲突,该补丁集的最新版本提供了一种解决产生软中断问题的方法,值得一看。
Workqueue 工作队列是利用内核线程来异步执行工作任务的通用机制,利用进程上下文来执行中断处理中耗时的任务,因此它允许睡眠。而 Softirq 和 Tasklet 在处理任务时不能睡眠。Softirq 是内核中常见的一种下半部机制,适合系统对性能和实时响应要求很高的场合,比如网络子系统,块设备,高精度定时器,RCU 等。
这篇文章主要记录使用 interrupt() 方法中断线程,以及如何对InterruptedException进行处理。感觉对InterruptedException异常进行处理是一件谨慎且有技巧的活儿。
-- 1. 继承 Thread 运行线程 : 重写 Thread 类的 run 方法, 然后执行该线程;
一个位5年的小伙伴去某东面试被一道并发编程的面试题给Pass了,说”如何中断一个正在运行中的线程?,这个问题很多工作2年的都知道,实在是有些遗憾。
在平时的开发过程中,相信都会使用到多线程,在使用多线程时,大家也会遇到各种各样的问题,今天我们就来说说一个多线程的问题——线程中断。在java中启动线程非常容易,大多数情况下我是让一个线程执行完自己的任务然后自己停掉,但是有时候我们需要取消某个操作,比如你在网络下载时,有时候需要取消下载。实现线程的安全中断并不是一件容易的事情,因为Java并不支持安全快速中断线程的机制,这里估计很多同学就会说了,java不是提供了Thread.interrupt 方法中断线程吗,好吧,我们今天就从这个方法开始说起。
| 导语 本文主要是讲Linux的调度系统, 由于全部内容太多,分三部分来讲,调度可以说是操作系统的灵魂,为了让CPU资源利用最大化,Linux设计了一套非常精细的调度系统,对大多数场景都进行了很多优化,系统扩展性强,我们可以根据业务模型和业务场景的特点,有针对性的去进行性能优化,在保证客户网络带宽前提下,隔离客户互相之间的干扰影响,提高CPU利用率,降低单位运算成本,提高市场竞争力。欢迎大家相互交流学习!
线程中断并不会使线程立即退出,而是给线程发送一个通知,告知目标线程,有人希望你退出了!至于目标线程接收到通知之后如何处理,则完全由目标线程自己决定
本文讲解了 Java 中线程中断的语法和应用场景,并给出了样例代码。线程中断指的是一个线程发送一个中断信号给另一个线程,通知其应该中断当前的执行。
Runnable和Callable是对任务的抽象,只有Thread是对线程的抽象。
interrupt()方法仅仅是在当前线程中打了一个停止标记,并不会真正的停止线程。 示例如下:
停止线程是指终止线程的运行,让线程从运行状态转变为终止状态。停止线程可以释放资源、节省系统资源,避免线程继续运行造成的安全问题和资源浪费。
1.对运行中的线程,仅设置了一个停止的标记,但程序照常运行。 2.对阻塞中的线程,该线程会抛出InterruptedException异常。
在Java程序中,我们想要停止一个线程可以通过interrupt方法进行停止。但是当我们调用interrupt方法之后,它可能并不会立刻就会停止线程,而是通知线程需要停止。线程接收到通知之后会根据自身的情况判断是否需要停止,它可能会立即停止,也有可能会执行一段时间后停止,也可能根本就不停止。
一般情况下,线程执行完成后就会结束,但有的时候我们可能需要在它正常执行完成前就停止它,可以考虑使用以下三种方法:
在写上一篇文章的时候就在想,executor.shutDown会不会把正在执行中的任务给中断了?虽然当时也分析过,但是当时确实只是泛泛而读,在实际中还是相当的模糊。借此机会,我们再复习一下。
这3个方法都是用于线程中断操作或判断的。那么,严格地讲,线程中断并不会是线程立即退出,而是给线程发送一个通知,告知目标线程有人希望你退出了,至于目标线程接到通知后如何处理,则完全由目标线程自行决定。 三个方法的区别: interrupt():中断线程,并添加中断状态。 interrupted():判断是否被中断,并清除当前中断状态。 isInterrupted():只是判断是否被中断,并不清除当前中断状态。 实例一:我们利用interrupt()来打断线程 📷 实例二:利用interrupted()清除中断
作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。为使更多童鞋受益,现给出开源框架地址:
中断线程最好的,最受推荐的方式是,使用共享变量(shared variable)发出信号,告诉线程必须停止正在运行的任务。线程必须周期性的核查这一变量(尤其在冗余操作期间),然后有秩序地中止任务。结合:使用Thread.interrupt()中断线程
1、shutdown()方法是安全的关闭线程池,调用shutdown方法后,不是立即关闭线程池,而是在线程池中执行很多任务,或者等待队列中执行任务,等待所有任务完成后关闭线程池
Java 线程使用一种机制来表想要终止他。这个中断机制依靠线程对象来检查当前线程是否需要中断,同时对象也可以决定是否响应中断请求。
在现代操作在运行一个程序时,会为其创建一个进程。例如启动一个QQ程序,操作系统就会为其创建一个进程。而操作系统中调度的最小单位元是线程,也叫轻量级进程,在一个进程里可以创建多个线程,这些线程都拥有各自的计数器,堆栈和局部变量等属性,并且能够访问共享的内存变量。处理器在这些线程上高速切换,让使用者感觉到这些线程在同时执行。因此我们可以这样理解:
46、Java 中 interrupted 和 isInterrupted 方法有什么区别?
1.引言 当我们点击某个杀毒软件的取消按钮来停止查杀病毒时,当我们在控制台敲入quit命令以结束某个后台服务时……都需要通过一个线程去取消另一个线程正在执行的任务。Java没有提供一种安全直接的方法来停止某个线程,但是Java提供了中断机制。 如果对Java中断没有一个全面的了解,可能会误以为被中断的线程将立马退出运行,但事实并非如此。中断机制是如何工作的?捕获或检测到中断后,是抛出InterruptedException还是重设中断状态以及在方法中吞掉中断状态会有什么后果?Thread.stop与中断
在Java中没有一种安全的抢占式方法来停止线程任务。只有一些协作式的机制,使请求取消的任务和代码都遵循一种协商好的协议。
首先,一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止。所以,Thread.stop, Thread.suspend, Thread.resume 都已经被废弃了。
1.引言 当我们点击某个杀毒软件的取消按钮来停止查杀病毒时,当我们在控制台敲入quit命令以结束某个后台服务时……都需要通过一个线程去取消另一个线程正在执行的任务。Java没有提供一种安全直接的方法来停止某个线程,但是Java提供了中断机制。 如果对Java中断没有一个全面的了解,可能会误以为被中断的线程将立马退出运行,但事实并非如此。中断机制是如何工作的?捕获或检测到中断后,是抛出InterruptedException还是重设中断状态以及在方法中吞掉中断状态会有什么后果?Thread.stop与中
Java有两个线程池类:ThreadPoolExecutor和ScheduledThreadPoolExecutor,且均继承于ExecutorService。Java API提供了Executors工厂类来帮助创建各种线程池。 Java线程池ExecutorService继承树:
当我们点击某个杀毒软件的取消按钮来停止查杀病毒时,当我们在控制台敲入quit命令以结束某个后台服务时……都需要通过一个线程去取消另一个线程正在执行的任务。Java没有提供一种安全直接的方法来停止某个线程,但是Java提供了中断机制。
线程池是并发中一项常用的优化方法,通过对线程复用,减少线程的创建,降低资源消耗,提高程序响应速度。在 Java 中我们一般通过 Exectuors 提供的工厂方法来创建线程池,但是线程池的最终实现类是 ThreadPoolExecutor,下面我们详细分析一下 ThreadPoolExecutor 的实现。
这看似一个完全没有意义的问题,但是如果你是从搜索引擎过来的话,那么说明你碰到过这个问题。 线程执行完不就退出了,说停止有什么意义? 当然有意义,意义在于,一般创建线程后,如果是一次性的线程,执行结束就可以了,不用管它。 如果是一个一直需要保持运行,而需要在某一时刻才需要停止的线程,就需要关注线程是如何退出的。
一般的代码中,尤其是作为一个基础类库时,绝不应当吞掉中断,即捕获到InterruptedException后在catch里什么也不做,清除中断状态后又不重设中断状态也不抛出InterruptedException等。因为吞掉中断状态会导致方法调用栈的上层得不到这些信息。 当然,凡事总有例外的时候,当你完全清楚自己的方法会被谁调用,而调用者也不会因为中断被吞掉了而遇到麻烦,就可以这么做。 总得来说,就是要让方法调用栈的上层获知中断的发生。假设你写了一个类库,类库里有个方法amethod,在amethod中检测并清除了中断状态,而没有抛出InterruptedException,作为amethod的用户来说,他并不知道里面的细节,如果用户在调用amethod后也要使用中断来做些事情,那么在调用amethod之后他将永远也检测不到中断了,因为中断信息已经被amethod清除掉了。如果作为用户,遇到这样有问题的类库,又不能修改代码,那该怎么处理?只好在自己的类里设置一个自己的中断状态,在调用interrupt方法的时候,同时设置该状态,这实在是无路可走时才使用的方法。 2、 中断的响应 程序里发现中断后该怎么响应?这就得视实际情况而定了。有些程序可能一检测到中断就立马将线程终止,有些可能是退出当前执行的任务,继续执行下一个任务……作为一种协作机制,这要与中断方协商好,当调用interrupt会发生些什么都是事先知道的,如做一些事务回滚操作,一些清理工作,一些补偿操作等。若不确定调用某个线程的interrupt后该线程会做出什么样的响应,那就不应当中断该线程。 4. Thread.interrupt VS Thread.stop Thread.stop方法已经不推荐使用了。而在某些方面Thread.stop与中断机制有着相似之处。如当线程在等待内置锁或IO时,stop跟interrupt一样,不会中止这些操作;当catch住stop导致的异常时,程序也可以继续执行,虽然stop本意是要停止线程,这么做会让程序行为变得更加混乱。 那么它们的区别在哪里?最重要的就是中断需要程序自己去检测然后做相应的处理,而Thread.stop会直接在代码执行过程中抛出ThreadDeath错误,这是一个java.lang.Error的子类。 在继续之前,先来看个小例子: 01 package com.ticmy.interrupt; 02 import java.util.Arrays; 03 import java.util.Random; 04 import java.util.concurrent.TimeUnit; 05 public class TestStop { 06 private static final int[] array = new int[80000]; 07 private static final Thread t = new Thread() { 08 public void run() { 09 try { 10 System.out.println(sort(array)); 11 } catch (Error err) { 12 err.printStackTrace(); 13 } 14 System.out.println("in thread t"); 15 } 16 }; 17 18 static { 19 Random random = new Random(); 20 for(int i = 0; i < array.length; i++) { 21 array[i] = random.nextInt(i + 1); 22 } 23 } 24 25 private static int sort(int[] array) { 26 for (int i = 0; i < array.length-1; i++){ 27 for(int j = 0 ;j < a
该方法可以用来请求中断线程。当一个线程调用该方法时,会设置该线程的中断标识位,线程执行的过程中会去检查这个标志位从而抛出异常。
比如说,当线程 A 正在运行时,线程 B 可以通过中断线程 A,来指示线程 A 停止它正在执行的操作。但是线程 A 如何响应线程 B 的中断,是需要依靠线程 A 的代码处理逻辑来做决定的。
“ 在前面分析Condition的时候,被阻塞的线程在我关闭应用的时候,会抛出异常,这是因为阻塞的线程被其他线程中断了。其实在学习AQS的时候我们也说过线程中断,AQS中acquire方法会忽略线程中断。现在我们来了解一下什么叫线程中断”
简单了解上面的例子,创建一个线程 启动,睡眠一秒钟后中断该线程, 中断该线程之后, 通过isInterrupted()方法得到该线程的状态为true,这个时候会跳出while循环。
以上大家可以看出来了吧,其实就是在循环的条件上做手脚就好了,因为每次循环都会根据这个while条件来判断的,所以在开启线程之后休眠3秒之后在将while条件设置为false就可以跳出循环了,随之也会自动停止线程了。
本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!
前面的几篇文章主要介绍了线程的一些最基本的概念,包括线程的间的冲突及其解决办法,以及线程间的协作机制。本篇主要来学习下Java中对线程中断机制的实现。在我们的程序中经常会有一些不达到目的不会
领取专属 10元无门槛券
手把手带您无忧上云