interrupt方法(java中interrupt)

本文目录
- java中interrupt
- Thread的interrupt机制
- java线程问题
- 关于java中的interrupt()方法疑问
- c线程被打断异常
- 关于线程 interrupt
- Java 多线程 关于 interrupt()方法
- Java如何中断一个正在运行的线程
java中interrupt
JDK API的说明如下:
public void interrupt()
中断线程。
如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的 checkAccess 方法就会被调用,这可能抛出 SecurityException。
如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。
如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException。
如果该线程在一个 Selector 中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup 方法一样。
如果以前的条件都没有保存,则该线程的中断状态将被设置。
中断一个不处于活动状态的线程不需要任何作用。
抛出:
SecurityException - 如果当前线程无法修改该线程。
注意这句:如果当前线程没有中断它自己(这在任何情况下都是允许的)
说明调用interrupt方法不一定会真的中断线程。
Thread的interrupt机制
当调用线程的 interrupt() 方法时,被打断的线程不会立刻被打断,只是它里面的一个 状态被改变 .
被中断线程可以通过interrupted()对状态进行检测,如果是被中断状态时,返回true,然后注意,此时的 中断状态会被重置到未被打断状态 ,因此,被中断线程可以通过调用一次该值不做任何处理,让自己不被中断.
内部调用本地方法 private native boolean isInterrupted(boolean ClearInterrupted); 参数为false.
而上面的interrupted()方法也是调用了这个本地方法,只不过参数为ture.
另外的线程调用一个 正在sleep(),或者wait()的线程 的interrupt方法时,此时 被中断线程会抛出一个异常 ,说明在休眠的线程中断是会被通知的,且此时的 中断状态为false ,也就是说中断休眠的线程是不会成功的,所以线程还是要自我打断的。
***隐藏网址***
java线程问题
interrupt():中断线程
stop():强迫线程停止执行。用 Thread.stop 来终止线程将释放它已经锁定的所有监视器(作为沿堆栈向上传播的未检查 ThreadDeath 异常的一个自然后果)。如果以前受这些监视器保护的任何对象都处于一种不一致的状态,则损坏的对象将对其他线程可见,这有可能导致任意的行为。
yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。yield()只能使同优先级的线程有执行的机会。----这句是重点
3.书上说yelid()是礼让,是让当前执行线程停下来给别的线程资源, 又说没有任何机制保证会这样。----------没有任何机制保证执行yield()的线程一定会把资源让给其它线程。打个比方:两个人抢东西,A抢到了B没有,再把东西放回去重抢,说不定还是A抢到B没有。没有任何机制保证放回去后B一定能抢到
关于java中的interrupt()方法疑问
在java中,开启一个多线程是很简单的,只需要new一个runnable就可以了,但是要停止一个线程,却不能简单的使用Thread.stop()方法。
首先来说说java中的中断机制,Java
中断机制是一种协作机制,也就是说通过中断并不能直接终止另一个线程,而需要被中断的线程自己处理中断。当调用interrupt()方法的时候,只是设
置了要中断线程的中断状态,而此时被中断的线程的可以通过isInterrupted()或者是interrupted()方法判断当前线程的中断状态是
否标志为中断。我们可以从interrupt()方法来看:
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt();
return;
}
}
interrupt0();
}
从这个方法中我们可以看到,最直接的调用时interrupt0()这个方法,而这个方法仅仅是设置了线程中断状态。
我们再看看isInterrupted()方法:
public boolean isInterrupted() {
return isInterrupted(false);
}
/**
* Tests if some Thread has been interrupted. The interrupted state
* is reset or not based on the value of ClearInterrupted that is
* passed.
*/
private native boolean isInterrupted(boolean ClearInterrupted);
从这个方法中,我们可以猜测到,isInterrupted()方法仅仅是检查了当前线程的中断状态,但是不会清除这个状态。
我们再来看看静态方法interrupted()
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
这个方法同样是检测当前线程的中断状态,但是这个方法会产生一个副作用,就是会清除当前线程的中断状态。
Thread.interrupt() VS Thread.stop()
这两个方法最大的区别在于:interrupt()方法是设置线程的中断状态,让用户自己选择时间地点去结束线程;而stop()方法会在代码的运行处直接抛出一个ThreadDeath错误,这是一个java.lang.Error的子类。所以直接使用stop()方法就有可能造成对象的不一致性。
调用Thread.sleep()方法的时候,如果当前线程处于中断那状态,那么sleep()方法不会执行,同时会清除掉该状态,并且抛出interruptedException异常。
中断的使用demo:
package com.app.basic;
public class InterruptTest {
public static void main(String args) {
Runnable runnable1 = new Runnable() {
@Override
public void run() {
for (int i = 0; i 《 10; i++) {
System.out.println(i);
if (Thread.currentThread().isInterrupted()) {
System.out.println("aa");
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
//sleep方法抛出这个异常之后会清除中断状态,所以需要重新设置中断状态
Thread.currentThread().interrupt();
}
}
}
};
final Thread t1 = new Thread(runnable1);
Runnable runnable2 = new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
t1.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread(runnable2);
t1.start();
t2.start();
c线程被打断异常
线程中断方法主要是两种:
.isInterrupted()是否为中断状态
interrupt()设置为中断
线程中断,并非真正的线程中断,而只是将线程的中断状态标识设置为true,由线程自己根据状态标识进行相应的业务处理逻辑,而线程实际上还在进行。
要区别于InterruptedException异常,一般的,线程会因为BlockingQueue#put、BlockingQueue#take、Object#wait、Thread#sleep以上状态被打断而抛出异常,这个异常是真正的线程中断,而与线程的中断状态标识没有任何关系,标识状态依然为false。
所以,这就需要注意一个问题,千万不能捕获了InterruptedException而不做中断处理,否则业务逻辑依然以为你没有中断,依然走正常的异常逻辑
二、示例代码
文章知识点与官方知识档案匹配
Java技能树首页概览
92423 人正在系统学习中
打开CSDN APP,看更多技术内容
线程中断的几种方式_坚持与努力的博客_线程中断
有三种方法可以使终止线程。1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。3. 使用interrupt方法中断线程...
继续访问
线程中断解析_叶小希的博客_线程中断状态
// 如果线程不响应中断 无法中断线程 t.interrupt(); // jvm不建议使用的方法 会让线程之间介绍,线程状态未知的情况下 将线程结束 // t.stop(); } 常见check的代码 if(Thread.interrupted()){// 会清理掉中断状态 ...
继续访问
java 线程 异常中断_java多线程并发之旅-19-InterruptedException 中断异常处理及中断机制...
引言如果对 Java 中断没有一个全面的了解,可能会误以为被中断的线程将立马退出运行,但事实并非如此。中断机制是如何工作的?捕获或检测到中断后,是抛出 InterruptedException 还是重设中断状态以及在方法中吞掉中断状态会有什么后果?Thread.stop 与中断相比又有哪些异同?什么情况下需要使用中断?线程池中的异常如何处理?中断处理的最佳实践?线程中断基础知识1、interrup...
继续访问
什么是线程中断?
下面的这断代码大家应该再熟悉不过了,线程休眠需要捕获或者抛出线程中断异常,也就是你在睡觉的时候突然有个人冲进来把你吵醒了。 try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } 此时线程被打断后,代码会继续运行或者抛出异常结束运行,这并不是我们需要的中断线程的作用。 到底是什么是线程中断? 线程中断即线程运行过程中被其他线程给打断了,它与 stop 最大的区别是:stop 是由系
继续访问
java阻塞线程中断_线程阻塞,线程中断,何时以及如何响应中断
2. sleep()造成的线程阻塞可以中断,而IO和synchronized造成的阻塞不可中断(即不能响应中断请求) 中断 不可中断阻塞 的方法: 关闭在其上发生阻塞的底层资源.比如 IO阻塞时不可中断, 在关闭这个IO时便可以中断. ...
继续访问
【线程】线程中断详解
文章目录中断线程判断线程是否被中断如何中断线程(中断原理)底层中断异常处理方式 中断线程 线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。 它并不像stop方法那样会中断一个正在运行的线程。 判断线程是否被中断 判断某个线程是否已被发送过中断请求,请使用Thread.currentThr
继续访问
并发编程之LockSupport的 park 方法及线程中断响应
并发编程之LockSupport的 park 方法及线程中断响应
继续访问
Java并发基础学习(二)——线程的停止和中断
前言 上一篇博客简单介绍了线程启动的方式,这一篇博客打算介绍一下如何停止线程,Java中停止线程相对来说就比较麻烦了,如何正确的停止线程其实也是一个比较常见的面试考题,需要详细总结一下。 线程停止的原理 Java中线程的停止并不是像关闭一个开关一样,直接停止线程,Java中的线程停止原理有点类似于计算机组成原理中对中断的处理,首先关闭中断标志位,让后响应中断,然后处理中断。 Java中线程的处理也可以看成大致的这个过程——**线程本身响应外部的中断通知,然后将中断标志位复位,但是什么之后线程停止,由线程本身
继续访问
线程响应中断
首先介绍下Thread的两个方法: interrupt():设置当前中断标记为true isInterrupted():检查线程的中断标记 @Slf4j public class StopThread implements Runnable { public static void main(String args) throws InterruptedException { ...
继续访问
对于Java线程中断的理解,哪种情况下会响应中断?哪种情况下不响应中断?
最近在学习JUC框架的时候,发现了很多工具类都是支持可中断的,如AQS、FutureTask都是可以在线程执行中,支持对于中断的响应,所以需要对线程中断有个了解,才能更好的学习JUC的源码。 线程中断的作用: 线程中断可以使一个线程从等待状态变成就绪状态,如果中断的线程正处于运行状态,那么这个中断是不会用任何作用的(表面上不会影响正在运行的线程),线程恢复到就绪状态后,可以继续执行逻辑代码,想要让一个线程从等待状态中恢复过来有三种发送:一.等待超时,二.得到一个通知...
继续访问
线程篇——线程的停止与中断
interrupt 还是先看下Thread类中interrupt方法的注释: Interrupts this thread. Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown. If this thread i
继续访问
线程的中断
我们都知道线程被终止一般有两个原因:一是run()方法正常执行完毕而自然死亡;二是因为一个没有捕获的异常终止了run方法而异外死亡。 当一个线程在正常执行完毕之前被中断是一件很可怕的事情,会出现很多意想不到的事情,比如不能归还锁而造成死锁现象,stop()方法和destroy()方法就是因此而被废弃的。 在前一篇博客中,我们尝试了利用一些变量以指示目标线程应该停止运行来达到线程终止的目的。在Jav...
继续访问
java关闭未执行完的线程_发现在JAVA中完全没办法用另一个线程去中断一个正在运行的线程,...
引用来自“爱吃大肉包”的答案引用来自“Grrrr”的答案真搞不懂,sun 已经推荐使用ExecutorService框架来处理thread了,为什么还是不用.Executor提供了管理终止的方法,以及可为跟踪一个或多个异步任务执行状况而生成 Future 的方法。可以关闭ExecutorService,这将导致其拒绝新任务。提供两个方法来关闭ExecutorService。shutdown()方法...
继续访问
线程中断Thread的interrupt()方法
什么时候需要关闭一个线程? 下面简单的举例情况: 比如我们会启动多个线程做同一件事,比如抢12306的火车票,我们可能开启多个线程从多个渠道买火车票,只要有一个渠道买到了,我们会通知取消其他渠道。这个时候需要关闭其他线程 很多线程的运行模式是死循环,比如在生产者/消费者模式中,消费者主体就是一个死循环,它不停的从队列中接受任务,执行任务,在停止程序时,我们需要一种”优雅”的方法以关闭该线程 在一些场景中,比如从第三方服务器查询一个结果,我们希望在限定的时间内得到结果,如果得不到,我们会希望取消该任务
继续访问
终止线程的方法
***隐藏网址***
继续访问
线程中断
线程中断就是处于运行状态的线程被强制打断。线程中断总体来说有三种方法:正常退出、stop暴力停止、interrupt异常停止。其中使用stop()方法是不安全的,可能导致数据不同步或者资源无法回收,目前stop()方法已经被标注为作废方法。一般使用interrupt停止线程,这里有几个与之相关的方法: public void interrupt() {} // 中断线程 public boo...
继续访问
Thread的中断机制(interrupt)
先看收集了别人的文章,全面的了解下java的中断: 中断线程 线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。它并不像stop方法那样会中断一个正在运行的线程。 判断线程...
继续访问
中断的线程化处理
中断的线程化处理 复杂、耗时的事情,尽量使用内核线程来处理。上节视频介绍的工作队列用起来挺简单,但是它有一个缺点:工作队列中有多个 work,前一个 work 没处理完会影响后面的 work。 解决方法有很多种,比如干脆自己创建一个内核线程,不跟别的 work 凑在一块了。 对于中断处理,还有另一种方法:threaded irq,线程化的中断处理。中断的处理仍然可以认为分为上半部、下半部。上半部用来处理紧急的事情,下半部用一个内核线程来处理,这个内核线程专用于这个中断。 你可以只提供 thread_fn,
继续访问
therading——多线程2
thread线程类基本介绍 class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}) 应该始终以关键字参数调用该构造函数。参数有: group应该为None;被保留用于未来实现了ThreadGroup类时的扩展。 target是将被run()方法调用的可调用对象。默认为None,表示不调用任何东西。 name是线程的名字。默认情况下,以“Thread-N”的形式构造一个唯一的名字,N是一个小的十进制整数.
继续访问
java线程中断
***隐藏网址***
继续访问
最新发布 线程中断方法
因为volatile能保证在多线程之间,一旦变量修改,能够立马通知到其他持有该变量的线程值被改变。所以我们可以利用volatile这个特性来实现线程中断。interrupted()查询当前线程阻塞状态,并将状态设置为false。备注操作线程不能处于sleep,wait,join,不然会抛出异常。interrupt()设置线程状态为true。isInterrupt()查询当前线程阻塞状态。...
继续访问
java线程的中断与恢复_Java 如何中断和恢复线程的执行
一、线程的状态线程可以阻塞于四种状态:1、当线程执行Thread.sleep()时,它一直阻塞到指定的毫秒时间之后,或者阻塞被另一个线程打断;2、当线程碰到一条wait()语句时,它会一直阻塞到接到通知notify()、被中断、经过了指定时间为止(若有超时值的话)3、线程阻塞与不同I/O的方式3.1. 常见的一种方式是InputStream的read()方法,该方法一直阻塞到从流中读取一个字节的数...
继续访问
线程响应中断
关于线程 interrupt
Thread有四个interrupt相关的方法interrupt()、interrupted()、isInterrupted()、isInterrupted(boolean ClearInterrupted),他们分别的作用是什么?
sleep()、wait()、join()这些方法抛出的InterruptedException跟这几个方法又有什么关系?
我们查看interrupt()、interrupted()、isInterrupted()、isInterrupted(boolean ClearInterrupted)这四个方法的注释,会发现都提到了一个状态interrupt status,这个状态true/false即为线程状态的一个标识位, 注意,这只是线程的一种中断机制,不一定会中断正在运行的线程,只是告诉线程选择在合适的时机中断自己。 这句话怎么理解呢?
也就是说我们的线程正常运行,外界通过一些操作改变了线程的interrupt status,线程并不会中断,只是改变了线程的interrupt status。
例1
例1 执行结果如下,可见interrupt方法只是改变了interrupt status,并没有中断线程的执行
sleep()、wait()、join()这些方法抛出的InterruptedException就跟interrupt status有关,这几个方法会一直监听interrupt status,一旦监听到这个status为true,则会抛出InterruptedException,并且会把这个状态clear为false。
例2
执行结果如下:
通过例1,我们知道调用interrupt方法,会把interrupt status置为true,而这里sleep监听interrupt status为true后会抛出InterruptedException,并且又将interrupt status重新clear为false,例2验证了这点。
现在理解了interrupt status这点后,我们就可以反过来看一下interrupt()、interrupted()、isInterrupted()、isInterrupted(boolean ClearInterrupted)这四个方法。
interrupt方法就是调用native方法将interrupt status置为true
isInterrupted()方法是一个native方法,会返回当前线程是否被interrupted,并且会根据传参ClearInterrupted来判断是否重置interrupt status
isInterrupted() 方法调用的上面的isInterrupted(boolean ClearInterrupted),并且传参false,说明会返回interrupt status,但是不会重置interrupt status
interrupted()方法也是调用的isInterrupted(boolean ClearInterrupted)方法,并且传参true,同样会返回interrupt status,并且会将状态重置为false
总结:线程的这种中断机制,是把线程的中断交给线程自己去处理,线程内部通过interrupt status去合理的中断线程,比如去清理资源等,而不是暴力的直接终止线程的运行。
Java 多线程 关于 interrupt()方法
1。interrupt()的作用是中断本线程的执行。
本线程中断自己是被允许的;其它线程调用本线程的interrupt()方法时,会通过checkAccess()检查权限。这有可能抛出SecurityException异常。
2。如果本线程是处于阻塞状态:调用线程的wait(), wait(long)或wait(long, int)会让它进入等待(阻塞)状态,或者调用线程的join(), join(long), join(long, int), sleep(long), sleep(long, int)也会让它进入阻塞状态。若线程在阻塞状态时,调用了它的interrupt()方法,那么它的“中断状态”会被清除并且会收到一个InterruptedException异常。例如,线程通过wait()进入阻塞状态,此时通过interrupt()中断该线程;调用interrupt()会立即将线程的中断标记设为“true”,但是由于线程处于阻塞状态,所以该“中断标记”会立即被清除为“false”,同时,会产生一个InterruptedException的异常。
3。如果线程被阻塞在一个Selector选择器中,那么通过interrupt()中断它时;线程的中断标记会被设置为true,并且它会立即从选择操作中返回。
如果不属于前面所说的情况,那么通过interrupt()中断线程时,它的中断标记会被设置为“true”。
4。中断一个“已终止的线程”不会产生任何操作。
Java如何中断一个正在运行的线程
程序是很简易的 然而 在编程人员面前 多线程呈现出了一组新的难题 如果没有被恰当的解决 将导致意外的行为以及细微的 难以发现的错误
在本篇文章中 我们针对这些难题之一 如何中断一个正在运行的线程
背景中断(Interrupt)一个线程意味着在该线程完成任务之前停止其正在进行的一切 有效地中止其当前的操作 线程是死亡 还是等待新的任务或是继续运行至下一步 就取决于这个程序 虽然初次看来它可能显得简单 但是 你必须进行一些预警以实现期望的结果 你最好还是牢记以下的几点告诫
首先 忘掉Thread stop方法 虽然它确实停止了一个正在运行的线程 然而 这种方法是不安全也是不受提倡的 这意味着 在未来的JAVA版本中 它将不复存在
一些轻率的家伙可能被另一种方法Thread interrupt所迷惑 尽管 其名称似乎在暗示著什么 然而 这种方法并不会中断一个正在运行的线程(待会将进一步说明) 正如Listing A中描述的那样 它创建了一个线程 并且试图使用Thread interrupt方法停止该线程 Thread sleep()方法的调用 为线程的初始化和中止提供了充裕的时间 线程本身并不参与任何有用的操作
class Example extends Thread { boolean stop=false; public static void main( String args ) throws Exception { Example thread = new Example (); System out println( Starting thread ); thread start(); Thread sleep( ); System out println( Interrupting thread ); thread interrupt(); Thread sleep( ); System out println( Stopping application ); //System exit( ); } public void run() { while(!stop){ System out println( Thread is running ); long time = System currentTimeMillis(); while((System currentTimeMillis() time 《 )) { } } System out println( Thread exiting under request ); } }
如果你运行了Listing A中的代码 你将在控制台看到以下输出
Starting thread Thread is running Thread is running Thread is running Interrupting thread Thread is running Thread is running Thread is running Stopping application Thread is running Thread is running Thread is running
甚至 在Thread interrupt()被调用后 线程仍然继续运行
真正地中断一个线程
中断线程最好的 最受推荐的方式是 使用共享变量(shared variable)发出信号 告诉线程必须停止正在运行的任务 线程必须周期性的核查这一变量(尤其在冗余操作期间) 然后有秩序地中止任务 Listing B描述了这一方式
Listing Bclass Example extends Thread { volatile boolean stop = false; public static void main( String args ) throws Exception { Example thread = new Example (); System out println( Starting thread ); thread start(); Thread sleep( ); System out println( Asking thread to stop ); thread stop = true; Thread sleep( ); System out println( Stopping application ); //System exit( ); } public void run() { while ( !stop ) { System out println( Thread is running ); long time = System currentTimeMillis(); while ( (System currentTimeMillis() time 《 ) && (!stop) ) { } } System out println( Thread exiting under request ); }}
运行Listing B中的代码将产生如下输出(注意线程是如何有秩序的退出的)
Starting thread Thread is running Thread is running Thread is running Asking thread to stop Thread exiting under request Stopping application
虽然该方法要求一些编码 但并不难实现 同时 它给予线程机会进行必要的清理工作 这在任何一个多线程应用程序中都是绝对需要的 请确认将共享变量定义成volatile 类型或将对它的一切访问封入同步的块/方法(synchronized blocks/methods)中
到目前为止一切顺利!但是 当线程等待某些事件发生而被阻塞 又会发生什么?当然 如果线程被阻塞 它便不能核查共享变量 也就不能停止 这在许多情况下会发生 例如调用Object wait() ServerSocket accept()和DatagramSocket receive()时 这里仅举出一些
他们都可能永久的阻塞线程 即使发生超时 在超时期满之前持续等待也是不可行和不适当的 所以 要使用某种机制使得线程更早地退出被阻塞的状态
很不幸运 不存在这样一种机制对所有的情况都适用 但是 根据情况不同却可以使用特定的技术 在下面的环节 我将解答一下最普遍的例子
使用Thread interrupt()中断线程
正如Listing A中所描述的 Thread interrupt()方法不会中断一个正在运行的线程 这一方法实际上完成的是 在线程受到阻塞时抛出一个中断信号 这样线程就得以退出阻塞的状态 更确切的说 如果线程被Object wait Thread join和 Thread sleep三种方法之一阻塞 那么 它将接收到一个中断异常(InterruptedException) 从而提早地终结被阻塞状态
因此 如果线程被上述几种方法阻塞 正确的停止线程方式是设置共享变量 并调用interrupt()(注意变量应该先设置) 如果线程没有被阻塞 这时调用interrupt()将不起作用 否则 线程就将得到异常(该线程必须事先预备好处理此状况) 接着逃离阻塞状态 在任何一种情况中 最后线程都将检查共享变量然后再停止 Listing C这个示例描述了该技术
Listing Cclass Example extends Thread { volatile boolean stop = false; public static void main( String args ) throws Exception { Example thread = new Example (); System out println( Starting thread ); thread start(); Thread sleep( ); System out println( Asking thread to stop ); thread stop = true;//如果线程阻塞 将不会检查此变量 thread interrupt(); Thread sleep( ); System out println( Stopping application ); //System exit( ); } public void run() { while ( !stop ) { System out println( Thread running ); try { Thread sleep( ); } catch ( InterruptedException e ) { System out println( Thread interrupted ); } } System out println( Thread exiting under request ); }}
一旦Listing C中的Thread interrupt()被调用 线程便收到一个异常 于是逃离了阻塞状态并确定应该停止 运行以上代码将得到下面的输出
Starting thread Thread running Thread running Thread running Asking thread to stop Thread interrupted Thread exiting under request Stopping application
中断I/O操作
然而 如果线程在I/O操作进行时被阻塞 又会如何?I/O操作可以阻塞线程一段相当长的时间 特别是牵扯到网络应用时 例如 服务器可能需要等待一个请求(request) 又或者 一个网络应用程序可能要等待远端主机的响应
如果你正使用通道(channels)(这是在Java 中引入的新的I/O API) 那么被阻塞的线程将收到一个 ClosedByInterruptException异常 如果情况是这样 其代码的逻辑和第三个例子中的是一样的 只是异常不同而已
但是 你可能正使用Java 之前就存在的传统的I/O 而且要求更多的工作 既然这样 Thread interrupt()将不起作用 因为线程将不会退出被阻塞状态 Listing D描述了这一行为 尽管interrupt()被调用 线程也不会退出被阻塞状态
Listing Dimport java io *;class Example extends Thread { public static void main( String args ) throws Exception { Example thread = new Example (); System out println( Starting thread ); thread start(); Thread sleep( ); System out println( Interrupting thread ); thread interrupt(); Thread sleep( ); System out println( Stopping application ); //System exit( ); } public void run() { ServerSocket socket; try { socket = new ServerSocket( ); } catch ( IOException e ) { System out println( Could not create the socket ); return; } while ( true ) { System out println( Waiting for connection ); try { Socket sock = socket accept(); } catch ( IOException e ) { System out println( accept() failed or interrupted ); } } }}
很幸运 Java平台为这种情形提供了一项解决方案 即调用阻塞该线程的套接字的close()方法 在这种情形下 如果线程被I/O操作阻塞 该线程将接收到一个SocketException异常 这与使用interrupt()方法引起一个InterruptedException异常被抛出非常相似
唯一要说明的是 必须存在socket的引用(reference) 只有这样close()方法才能被调用 这意味着socket对象必须被共享 Listing E描述了这一情形 运行逻辑和以前的示例是相同的
Listing Eimport *;import java io *;class Example extends Thread { volatile boolean stop = false; volatile ServerSocket socket; public static void main( String args ) throws Exception { Example thread = new Example (); System out println( Starting thread ); thread start(); Thread sleep( ); System out println( Asking thread to stop ); thread stop = true; thread socket close(); Thread sleep( ); System out println( Stopping application ); //System exit( ); } public void run() { try { socket = new ServerSocket( ); } catch ( IOException e ) { System out println( Could not create the socket ); return; } while ( !stop ) { System out println( Waiting for connection ); try { Socket sock = socket accept(); } catch ( IOException e ) { System out println( accept() failed or interrupted ); } } System out println( Thread exiting under request ); }}
以下是运行Listing E中代码后的输出
Starting thread Waiting for connection Asking thread to stop accept() failed or interrupted Thread exiting under request Stopping application
多线程是一个强大的工具 然而它正呈现出一系列难题 其中之一是如何中断一个正在运行的线程 如果恰当地实现 使用上述技术中断线程将比使用Java平台上已经提供的内嵌操作更为简单 lishixinzhi/Article/program/Java/gj/201311/27481
更多文章:
ie地址栏不见了(如何解决IE11浏览器工具栏不见了的问题)
2026年9月22日 19:00
十年前的老电脑怎么装win7(2011年买的惠普笔记本电脑,后来系统升级到了win10,现在有需要换成win7,怎么u盘重装系统)
2026年9月22日 14:40
windowsxpsp3官方原版(Windows XP SP3微软官方原版怎么安装)
2026年9月22日 14:30
蓝屏000007e解决方法(电脑蓝屏代码0x0000007E是什么问题啊)
2026年9月22日 12:40





