美文网首页
java线程之中断线程Interrupted用法

java线程之中断线程Interrupted用法

作者: 小陈阿飞 | 来源:发表于2018-05-18 14:28 被阅读36次

中断线程-interrupt()

一个正在运行的线程除了正常的时间片中断之外,能否被其他线程控制?或者说其他线程能否让指定线程放弃CPU或者提前结束运行? 除了线程同步机制之外,还有两种方法:
(1) Thread.stop(), Thread.suspend(), Thread.resume() 和Runtime.runFinalizersOnExit() 这些终止线程运行的方法 。这些方法已经被废弃,使用它们是极端不安全的。

这里的 「stop」方法,和「resume」方法、「suspend」方法并称 Thread 三少,因为线程安全问题,都已经被 @Deprecated 了。。
当我们停止一个线程时,它会悄悄的把所持有的 monitor 锁释放了,此时,其他依赖锁的线程可能就会抢到锁执行。关键此时,当前 stop 的线程实际并没有处理完所有先决条件,可能这个时候就产生了诡异的问题,加班的日子可能就悄悄来了。

那你说 「Stop 不让用了,总得让我们有办法处理线程吧,哪怕通知他,打断他一下,让他停止」。

(2) Thread.interrupt() 方法是很好的选择。但是使用的时候我们必须好好理解一下它的用处。

//无法中断正在运行的线程代码    
class TestRunnable implements Runnable{    
      public void run(){    
            while(true)    
            {    
                  System.out.println( "Thread is running..." );    
                  long time = System.currentTimeMillis();//去系统时间的毫秒数    
            while((System.currentTimeMillis()-time < 1000)) {    
                   //程序循环1秒钟,不同于sleep(1000)会阻塞进程。    
            }    
              }    
       }    
}    
public class ThreadDemo{    
         public static void main(String[] args){    
               Runnable r=new TestRunnable();    
               Thread th1=new Thread(r);    
               th1.start();    
               th1.interrupt();             
        }    
}    

运行结果:一秒钟打印一次Thread is running...。程序没有终止的任何迹象 ,说明interrupt并不能中断线程执行。

首先我们看看interrupt究竟在干什么。

当我们调用th1.interrput()的时候,线程th1的中断状态(interrupted status) 会被置位。我们可以通过Thread.currentThread().isInterrupted() 来检查这个布尔型的中断状态。

在Core Java中有这样一句话:"没有任何语言方面的需求要求一个被中断的程序应该终止。中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断 "。好好体会这句话的含义,看看下面的代码:

//Interrupted的经典使用代码    
public void run(){    
        try{    
             ....    
             while(!Thread.currentThread().isInterrupted()&& more work to do){    
                    // do more work;    
             }    
        }catch(InterruptedException e){    
                    // thread was interrupted during sleep or wait    
        }    
        finally{    
                   // cleanup, if required    
        }    
}    

很显然,在上面代码中,while循环有一个决定因素就是需要不停的检查自己的中断状态。当外部线程调用该线程的interrupt 时,使得中断状态置位。这是该线程将终止循环,不在执行循环中的do more work了。

这说明: interrupt中断的是线程的某一部分业务逻辑,前提是线程需要检查自己的中断状态(isInterrupted())。

但是当th1被阻塞的时候,比如被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞时。调用它的interrput()方法。可想而知,没有占用CPU运行的线程是不可能给自己的中断状态置位的。这就会产生一个InterruptedException异常。

 //中断一个被阻塞的线程代码  
class TestRunnable implements Runnable{  
     public void run(){  
          try{  
        Thread.sleep(1000000); //这个线程将被阻塞1000秒  
       }catch(InterruptedException e){  
         e.printStackTrace();  
                     //do more work and return.  
          }  
     }  
}  
public class TestDemo2{  
      public static void main(String[] args) {  
            Runnable tr=new TestRunnable();  
            Thread th1=new Thread(tr);  
            th1.start(); //开始执行分线程  
        while(true){  
            th1.interrupt();  //中断这个分线程  
        }  
      }  
}  
   /*运行结果: 
   java.lang.InterruptedException: sleep interrupted 
        at java.lang.Thread.sleep(Native Method) 
        at TestRunnable.run(TestDemo2.java:4) 
        at java.lang.Thread.run(Unknown Source)*/  
强调一个知识:isInterrupted和interrupted区别

两者都是获取interrupt状态,但是interrupted方法在获取状态后,会重置状态。isInterrupted则不会重置状态。

相关文章

  • java线程之中断线程Interrupted用法

    中断线程-interrupt() 一个正在运行的线程除了正常的时间片中断之外,能否被其他线程控制?或者说其他线程能...

  • JAVA线程池常见用法及其原理

    JAVA线程池常见用法及其原理 JAVA线程池常见用法: 1.代码实现 import lombok.extern....

  • JAVA线程池常见用法

    JAVA线程池常见用法及其原理 1.JAVA线程池常见用法: 2.核心参数讲解 corePoolSize: 核心线...

  • java_多线程

    java_多线程 线程创建方式;join用法; sleep和wait区别; 线程安全和不安全的java集合; St...

  • Java循环线程

    正确的线程循环写法: 用一个boolean变量或者 线程的Interrupted标志位来判断。 停止线程时,调用,...

  • Java @ synchronized

    参考: Java中Synchronized的用法 Java 多线程:synchronized 关键字用法(修饰类,...

  • Android常用的线程池

    Android应用开发是一种多线程编程,Android中的线程概念源于Java,所以线程的用法也直接用的是Java...

  • Java基础17-多线程

    概述 本文主要讲java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的线程函数用法等。首先让我们来了...

  • Synchronized的原理分析

    Java多线程运行环境中,在哪些情况下会使对象锁释放?释放锁: 不释放锁的情况: interrupted()和is...

  • Android多线程基础

    线程的基本用法 Android多线程编程并不比Java多线程编程特殊,基本都是使用相同的语法。那么如何创建一个线程...

网友评论

      本文标题:java线程之中断线程Interrupted用法

      本文链接:https://www.haomeiwen.com/subject/dljgdftx.html