浅析java线程中断的办法

中断线程相关的方法

中断线程有一些相应的方法,这里列出来一下。

注意,如果是Thread.method(),则代表是静态方法。如果是thread.method()则代表着是类方法

void thread.stop()

这个方法能中断正在运行的线程,但是已经不推荐使用了,在将来的版本或许弃用,因为强行中断运行中的线程,是不安全的。

void thread.interrupt()

如果正在运行wait(),sleep(),join()这三个方法阻塞了线程,那么将会使得线程抛出InterruptedException异常,这是一个中断阻塞的过程。如果是其它的正在运行的状态,那么将不会有任何影响,也不会中断线程,或者抛出异常,只会会打上一个中断线程的标志,是否中断线程,将由程序控制。

boolean thread.isInterrupted()

它会获取当前线程的标志,如果之前调用过thread.interrupt(),那么它的返回值是true。它的作用就是返回该线程是否有中断标志。多次调用这个方法的结果是一样的。

void Thread.interrupted()

与前面的方法不一样的是,这是一个静态方法,代表着不需要拿到线程对象就可以直接执行,所以它的作用是返回当前线程是否有中断标志。但是它的区别是,当调用这个方法之后,会清除程序的中断标志,就是如果当前线程已中断,第一次调用这个方法的返回值是true,第二次调用这个方法的返回值为false,因为调用方法时,会清除它的中断标志。

中断线程

for循环标记退出

package com.xiaojiezhu.thread;

/**
 * @author xiaojie.zhu
 */
public class ThreadBreak implements Runnable {

  @Override
  public void run() {
    for(int i = 0 ; i < 10000 ; i ++){
      boolean interruped = Thread.currentThread().isInterrupted();
      if(interruped){
        //有中断标记,中断
        break;
      }
      System.out.println(i);
    }

    System.out.println("over");
  }

  public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(new ThreadBreak());
    t.start();
    Thread.sleep(1);

    t.interrupt();
  }
}

打印结果如下

44
45
46
47
over

阻塞的退出线程

只要是在运行wait(),sleep(),join()的方法,它就会声明一个InterruptedException异常,也就是意味着这些方法并不是一定能执行完成,因为当调用线程的interrupt()方法时,就会中断这个阻塞的办法,从而进入到异常中,代码如下

package com.xiaojiezhu.thread;

/**
 * @author xiaojie.zhu
 */
public class ThreadBreak2 implements Runnable {
  @Override
  public void run() {
    try {
      Thread.sleep(20000);
      System.out.println("这段话不会输出");
    } catch (InterruptedException e) {
      //如果在sleep()的过程中调用了interrupt()方法,就会进入这里,因为会强行中断sleep()

      //这里打印出来的中断标记为false,因为只要进入了InterruptedException异常,中断标记就会被清除掉
      System.out.println("中断标记为:" + Thread.currentThread().isInterrupted());
      System.out.println("输出异常");
      e.printStackTrace();
    }
  }

  public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(new ThreadBreak2());
    t.start();

    Thread.sleep(100);

    t.interrupt();

    System.out.println("over");
  }
}

打印结果如下

over
中断标记为:false
输出异常
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.xiaojiezhu.thread.ThreadBreak2.run(ThreadBreak2.java:10)
at java.lang.Thread.run(Thread.java:748)

注意:因为只要进入了InterruptedException异常,中断标记就会被清除掉

这里会衍生出另一种情况,就是如果在进入阻塞方法之前,就有了中断标记呢?会发生什么,就如下的代码:

for(int i = 0 ; i < 10000 ; i ++){
  System.out.println(i);
}
try {
  System.out.println("开始sleep");
  Thread.sleep(20000);
  System.out.println("结束sleep");

} catch (InterruptedException e) {
  e.printStackTrace();
}

实际上它会先执行完上面的for循环,因为for循环中是无法中止的,在进入sleep()的时候,瞬间就抛出异常

完整的测试代码如下

package com.xiaojiezhu.thread;

/**
 * @author xiaojie.zhu
 */
public class ThreadBreak3 implements Runnable {

  @Override
  public void run() {
    for(int i = 0 ; i < 10000 ; i ++){
      System.out.println(i);
    }
    try {
      System.out.println("开始sleep");
      Thread.sleep(20000);
      System.out.println("结束sleep");

    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

  public static void main(String[] args) {
    Thread thread = new Thread(new ThreadBreak3());
    thread.start();

    thread.interrupt();
  }
}

打印结果如下

9997
9998
9999
开始sleep
java.lang.InterruptedException: sleep interrupted
  at java.lang.Thread.sleep(Native Method)
  at com.xiaojiezhu.thread.ThreadBreak3.run(ThreadBreak3.java:15)
  at java.lang.Thread.run(Thread.java:748)

使用stop()方法停止线程

thread.stop()方法是一个不安全的方法,已经不推荐使用了,但是在目前的代码中,还能正常使用,我们不推荐这样使用,但是这里介绍一下

package com.xiaojiezhu.thread;

/**
 * @author xiaojie.zhu
 */
public class ThreadBreak4 implements Runnable {
  @Override
  public void run() {
    System.out.println("进入线程");
    try {
      Thread.sleep(20000);
      System.out.println("结束线程");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

  public static void main(String[] args) {
    Thread t = new Thread(new ThreadBreak4());
    t.start();
    try {
      Thread.sleep(200);

      t.stop();

      System.out.println("over");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

打印结果如下

进入线程
over

(0)

相关推荐

  • Java线程中断的本质深入理解

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

  • Java多线程中断机制三种方法及示例

    概述 之前讲解Thread类中方法的时候,interrupt().interrupted().isInterrupted()三个方法没有讲得很清楚,只是提了一下.现在把这三个方法同一放到这里来讲,因为这三个方法都涉及到多线程的一个知识点----中断机制. Java没有提供一种安全.直接的方法来停止某个线程,而是提供了中断机制.中断机制是一种协作机制,也就是说通过中断并不能直接终止另一个线程,而需要被中断的线程自己处理.有个例子举个蛮好,就像父母叮嘱出门在外的子女要注意身体一样,父母说了,但是子女

  • 深入Java线程中断的本质与编程原则的概述

    在历史上,Java试图提供过抢占式限制中断,但问题多多,例如前文介绍的已被废弃的Thread.stop.Thread.suspend和 Thread.resume等.另一方面,出于Java应用代码的健壮性的考虑,降低了编程门槛,减少不清楚底层机制的程序员无意破坏系统的概率. 如今,Java的线程调度不提供抢占式中断,而采用协作式的中断.其实,协作式的中断,原理很简单,就是轮询某个表示中断的标记,我们在任何普通代码的中都可以实现. 例如下面的代码:    volatile bool isInter

  • Java检测线程中断状态的方法示例

    本文实例讲述了Java检测线程中断状态的方法.分享给大家供大家参考,具体如下: 一 代码 public class InterruptCheck { public static void main( String[] args ) throws Exception { // sleepThread不停尝试睡眠 Thread sleepThread = new Thread(new SleepRunner(), "SleepThread"); sleepThread.setDaemon(

  • Java多线程之中断线程(Interrupt)的使用详解

    interrupt方法 interrupt字面上是中断的意思,但在Java里Thread.interrupt()方法实际上通过某种方式通知线程,并不会直接中止该线程.具体做什么事情由写代码的人决定,通常我们会中止该线程. 如果线程在调用Object类的wait().wait(long)或wait(long, int)方法,或者该类的 join() .join(long) .join(long, int) .sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态

  • java多线程中断代码详解

    一.java中终止线程主要有三种方法: ①线程正常退出,即run()方法执行完毕了 ②使用Thread类中的stop()(已过期不推荐使用)方法强行终止线程. ③使用中断机制 t.stop()调用时,终止线程,会导致该线程所持有的锁被强制释放,从而被其他线程所持有,因此有可能导致与预期结果不一致.下面使用中断信号量中断非阻塞状态的线程中: public class TestStopThread { public static void main(String[] args) throws Int

  • Java中实现线程的超时中断方法实例

    背景 之前在实现熔断降级组件时,需要实现一个接口的超时中断,意思是,业务在使用熔断降级功能时,在平台上设置了一个超时时间,如果在请求进入熔断器开始计时,并且接口在超时时间内没有响应,则需要提早中断该请求并返回. 比如正常下游接口的超时时间为800ms,但是因为自身业务的特殊需求,最多只能等200ms,如果200ms之内没有数据返回,则返回降级数据.这里处理请求的线程可以看成是tomcat线程池中的一个线程,如果通过线程池返回的Future,可以很轻松的实现超时返回,但是这种情况下,并不能拿到Fu

  • 浅析Java线程的中断机制

    线程中断机制提供了一种方法,用于将线程从阻塞等待中唤醒,尝试打断目标线程的现有处理流程,使之响应新的命令.Java 留给开发者这一自由,我们应当予以善用. 今天我们聊聊 Java 线程的中断机制. 线程中断机制提供了一种方法,有两种常见用途: 将线程从阻塞等待中唤醒,并作出相应的"受控中断"处理. 尝试告知目标线程:请打断现有处理流程,响应新的命令. 以第一种用途为例,请看以下代码: synchronized (lock) { try { while (!check()) { lock

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

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

  • 详解Java线程中断知识点

    下面的这断代码大家应该再熟悉不过了,线程休眠需要捕获或者抛出线程中断异常,也就是你在睡觉的时候突然有个人冲进来把你吵醒了. try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } 此时线程被打断后,代码会继续运行或者抛出异常结束运行,这并不是我们需要的中断线程的作用. 到底是什么是线程中断? 线程中断即线程运行过程中被其他线程给打断了,它与 stop 最大的区别是:stop 是由系统强

  • 详解Java编程中对线程的中断处理

    1. 引言 当我们点击某个杀毒软件的取消按钮来停止查杀病毒时,当我们在控制台敲入quit命令以结束某个后台服务时--都需要通过一个线程去取消另一个线程正在执行的任务.Java没有提供一种安全直接的方法来停止某个线程,但是Java提供了中断机制. 如果对Java中断没有一个全面的了解,可能会误以为被中断的线程将立马退出运行,但事实并非如此.中断机制是如何工作的?捕获或检测到中断后,是抛出InterruptedException还是重设中断状态以及在方法中吞掉中断状态会有什么后果?Thread.st

随机推荐