Java线程的中断(Interruption)

  任务和线程的启动很容易。在大多数时候,我们都会让它们运行直到结束,或者让它们自行停止。然而,有时候我们希望提前结束任务或线程,或许是因为用户取消了操作,或者应用程序需要被快速关闭。 要使任务和线程能安仝、快速、可靠地停止下来,并不是一件容易的事。Java的Thread类为我们提供了stop(),suspend()等停止挂起线程的方法,但是由于安全问题目前都已被弃用。Java并没有提供一种安全的抢占式方法来停止线程,但它提供了中断(Interruption),这是一种协作机制,采用协作式的方式使一个线程终止另一个线程的当前工作。 这种协作式的方法是必要的,我们很少希望某个任务、线程或服务立即停止,因为这种立即停止会使共享的数据结构处于不一致的状态。相反,在编写任务和服务时可以使用一种协作的方式:当需要停止时,它们首先会清除当前正在执行的工作,然后再结束。这提供了更好的灵活性,因为任务本身的代码比发出取消请求的代码更清楚如何执行清除工作。 生命周期结束(End-of-Lifecycle)的问题会使任务、服务以及程序的设计和实现等过程变得复杂,而这个在程序设计中非常重要的要素却经常被忽略。一个在行为良好的软件与勉强运行的软件之间的最主要区别就是,行为良好的软件能很完善地处理失败、关闭和取消等过程。

  如何设计一种协作机制,让线程可以安全的中断呢?我们可以设置一个取消标志,在工作线程会被中断的地方去检查这个标志,当检查到这个中断标志被设置为已取消时,工作线程便开始做取消工作。

 1 public class CancelableThread implements Runnable {
 2
 3     //线程取消标志,volatile修饰,保证内存可见性
 4     private volatile boolean isCanceled = false;
 5
 6     @Override
 7     public void run() {
 8         while (!isCanceled) {//在工作线程中轮询检测这个取消标志
 9             System.out.println("The current thread is doing something...");
10             System.out.println(Thread.currentThread().getName() + " cancel flag is " + isCanceled);
11         }
12         //当取消标志被设置为true,执行以下代码,可以做一些取消工作
13         System.out.println(Thread.currentThread().getName() + "The current thread Has been cancelled");
14     }
15
16     private void cancel() {
17         isCanceled = true;
18     }
19 }
 1 public class Main {
 2     public static void main(String[] args) throws Exception {
 3
 4         CancelableThread cancelableThread = new CancelableThread();
 5         new Thread(cancelableThread).start();
 6         try {
 7             Thread.sleep(1);
 8         } finally {
 9             //设置标志位为true,中断线程
10       cancelableThread.cancel();
11         }
12     }
13 }

打印结果:

Thread-0 cancel flag is false
The current thread is doing something...
Thread-0 cancel flag is false
The current thread is doing something...
Thread-0 cancel flag is false
The current thread is doing something...
Thread-0 cancel flag is false
The current thread is doing something...
Thread-0 cancel flag is true
Thread-0The current thread Has been cancelled

 

其实Thread类为我们提供了三个与线程中断相关的方法,来实现上述机制。这三个方法分别是:

public void interrupt() {
  //...  省略相关代码
  interrupt0();           // Just to set the interrupt flag
  //...  省略相关代码
}
public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {
    return isInterrupted(false);
}
  1. interrupt()方法主要用来设置中断标志位;如果此线程在调用Object类的wait(),wait(long)或wait(long,int)方法或join(),join(long),join(long,int) ,sleep(long)或sleep(long,int)的方法阻塞时,那么它的中断状态将被清除,并且会收到一个InterruptedException异常。
  2. 静态的interrupted()方法用来测试当前线程是否被中断,调用此方法会清除线程的中断状态。如果线程已被中断,调用此方法返回false;
  3. isInterrupted()方法用来测试当前线程是否被中断,但是不会清除线程的中断状态。

查看源码发现,静态的interrupted()和isInterrupted()方法都是调用的 private native boolean isInterrupted(boolean ClearInterrupted);   根据传入的ClearInterrupted的值,来判断是否要清除中断标志位。

 1 public class InterruptTest {
 2
 3
 4     static class InnerThread extends Thread{
 5
 6
 7         @Override
 8         public void run() {
 9             while(!isInterrupted()){
10                 System.out.println(Thread.currentThread().getName()+" cancle flag is "+isInterrupted());
11                 try {
12
13                     Thread.sleep(100);
14
15                 }catch (InterruptedException e){
16                     e.printStackTrace();
17                     //抛出InterruptedException,中断标志位被清除,再次调用 interrupt();
18                     interrupt();
19                 }
20             }
21             System.out.println(Thread.currentThread().getName()+" cancle flag is "+isInterrupted());
22
23         }
24     }
25
26
27     public static void main(String[] args) {
28         InnerThread innerThread = new InnerThread();
29         innerThread.start();
30         try {
31
32             Thread.sleep(1000);
33
34         }catch (InterruptedException e){
35             e.printStackTrace();
36         }
37         innerThread.interrupt();
38 //        InnerThread innerThread2 = new InnerThread();
39 //        innerThread2.start();
40 //        innerThread2.interrupt();
41     }
42 }

打印结果:

Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at InterruptTest$InnerThread.run(InterruptTest.java:13)
Thread-0 cancle flag is true




原文地址:https://www.cnblogs.com/perkins/p/9052139.html

时间: 2024-12-19 03:16:22

Java线程的中断(Interruption)的相关文章

Java线程阻塞中断和LockSupport的常见问题

上周五和周末,工作忙里偷闲,在看java cocurrent中也顺便再温故了一下Thread.interrupt和java 5之后的LockSupport的实现. 在介绍之前,先抛几个问题. Thread.interrupt()方法和InterruptedException异常的关系?是由interrupt触发产生了InterruptedException异常? Thread.interrupt()会中断线程什么状态的工作? RUNNING or BLOCKING? 一般Thread编程需要关注

java线程的中断学习

<span style="font-size:18px;">package thread.java.test; /** * 在这里练习的是线程的中断 * Thread.interrupt()来设置中断状态是true,当一个线程运行时,另一个线程可以调用另一个 * 线程的interrupt()方法来中断他 * Thread.isInterrupt()来获取线程的中断状态 * Thread.interrupted()这是一个静态的方法,用来获取中断状态,并清除中断状态, * 其

java线程阻塞中断与LockSupport使用介绍

上周五和周末,工作忙里偷闲,在看java cocurrent中也顺便再温故了一下Thread.interrupt和java 5之后的LockSupport的实现. 在介绍之前,先抛几个问题. Thread.interrupt()方法和InterruptedException异常的关系?是由interrupt触发产生了InterruptedException异常? Thread.interrupt()会中断线程什么状态的工作? RUNNING or BLOCKING? 一般Thread编程需要关注

JAVA 线程基本知识汇总--线程中断

1.线程中断的结果专业术语 isInterrupted interrupted interrupt // 测试当前线程是否已经中断,同时会将线程的中断状态取消 Thread.interrupted(); // 在当前线程加上一个打断标记 ** 并不会真的立即停止线程 thread.interrupt(); // 测试线程是否已经中断 thread.isInterrupted(); 2.知识点: 直接调用interrupt 不会中断线程 package org.test; /*  * 线程中断演示

java线程中断和终止线程运行

ava中启动一个线程很容易,通常情况下我们都是等到任务运行结束后让线程自行停止.但有时需要在任务正在运行时取消他们,使得线程快速结束.对此Java并没有提供任何机制.但是我们可以通过Java提供的线程中断机制来实现. 首先来看Thread类三个和中断有关的方法: public class Thread { // 发出一个中断请求,把标志位设定为中断状态,不会终止线程运行. // 其他线程试图调用该方法,会检测是否有权限中断该线程(正常情况 // 下不会存在权限问题,这里可以忽略) public

java线程中断

java线程中断[interrupt()函数] http://vikings825.iteye.com/blog/964644 停止Java线程,小心interrupt()方法  这篇写的是怎么  正确的 停止 一个线程 http://blog.csdn.net/wxwzy738/article/details/8516253 聊聊并发——生产者消费者模式 http://www.infoq.com/cn/articles/producers-and-consumers-mode/

用interrupt()中断Java线程

最近在学习Java线程相关的东西,和大家分享一下,有错误之处欢迎大家指正. 假如我们有一个任务如下,交给一个Java线程来执行,如何才能保证调用interrupt()来中断它呢? Java代码   class ATask implements Runnable{ private double d = 0.0; public void run() { //死循环执行打印"I am running!" 和做消耗时间的浮点计算 while (true) { System.out.printl

lesson6:java线程中断

正常的情况下,业务系统都不会去中断它的线程,但是由于一些特殊情况的发生,线程已经不能正常结束了,并且此类线程已经影响到业务系统提供服务的能力,如果系统设计的健壮,便会通过监控线程去主动的中断此类线程.但是如果随意的去中断线程,又是非常危险的,因为线程内部会占用资源和改变变量的内容等,最好的办法是向线程发送中断信号,由线程自己去中断自己. 源码地址:https://github.com/mantuliu/javaAdvance 首先,我们先分析一下源代码用demo来看一下,stop()和suspe

Java线程中断的本质深入理解(转)

一.Java中断的现象 首先,看看Thread类里的几个方法: public static boolean interrupted 测试当前线程是否已经中断.线程的中断状态 由该方法清除.换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外). public boolean isInterrupted() 测试线程是否已经中断.线程的中断状态 不受该方法的影响. public void in