`
wuchangqing
  • 浏览: 6023 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

interrupt、interrupted、isInterrupted的区别

阅读更多

转自 http://blog.csdn.net/budapest/article/details/6941802

 

中断线程 —— interrupt() 

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

* 如果线程被阻塞,它便不能核查共享变量,也就不能停止。这在许多情况下会发生,例如调用
* Object.wait()、ServerSocket.accept()和DatagramSocket.receive()时,他们都可能永
* 久的阻塞线程。即使发生超时,在超时期满之前持续等待也是不可行和不适当的,所以,要使
* 用某种机制使得线程更早地退出被阻塞的状态。很不幸运,不存在这样一种机制对所有的情况
* 都适用,但是,根据情况不同却可以使用特定的技术。使用Thread.interrupt()中断线程正
* 如Example1中所描述的,Thread.interrupt()方法不会中断一个正在运行的线程。这一方法
* 实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更
* 确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,
* 它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。

 

----------------------------------------------------------------------------------------------------------------------------------

 

1、interrupt 

 

interrupt方法用于中断线程。调用该方法的线程的状态为将被置为"中断"状态。

 

注意:线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态为并做处理。支持线程中断的方法(也就是线程中断后会抛出interruptedException的方法)就是在监视线程的中断状态,一旦线程的中断状态被置为“中断状态”,就会抛出中断异常。

 


2、interrupted 和 isInterrupted

 

首先看一下该方法的实现:

 

1 public static boolean interrupted () {
2      return currentThread().isInterrupted(true);
3 }

 

该方法就是直接调用当前线程的isInterrupted(true)方法。

 

然后再来看一下 isInterrupted的实现:

 

1 public boolean isInterrupted () {
2      return isInterrupted( false);
3 }

 

这两个方法有两个主要区别:

 

  1. interrupted 是作用于当前线程,isInterrupted 是作用于调用该方法的线程对象所对应的线程。(线程对象对应的线程不一定是当前运行的线程。例如我们可以在A线程中去调用B线程对象的isInterrupted方法。)
  2. 这两个方法最终都会调用同一个方法,只不过参数一个是true,一个是false;

 


 

第二个区别主要体现在调用的方法的参数上,让我们来看一看这个参数是什么含义

 


 

先来看一看被调用的方法 isInterrupted(boolean arg)的定义:

 

1 private native boolean isInterrupted( boolean ClearInterrupted);

 

原来这是一个本地方法,看不到源码。不过没关系,通过参数名我们就能知道,这个参数代表是否要清除状态位。

 

如果这个参数为true,说明返回线程的状态位后,要清掉原来的状态位(恢复成原来情况)。这个参数为false,就是直接返回线程的状态位。

 

这两个方法很好区分,只有当前线程才能清除自己的中断位(对应interrupted()方法)

 

 

 

 

 

是不是这样理解呢,
Thread.currentThread().interrupt(); 这个用于清除中断状态,这样下次调用Thread.interrupted()方法时就会一直返回为true,因为中断标志已经被恢复了。
而调用isInterrupted 只是简单的查询中断状态,不会对状态进行修改。

interrupt()是用来设置中断状态的。返回true说明中断状态被设置了而不是被清除了。我们调用sleep、wait等此类可中断(throw InterruptedException)方法时,一旦方法抛出InterruptedException,当前调用该方法的线程的中断状态就会被jvm自动清除了,就是说我们调用该线程的isInterrupted 方法时是返回false。如果你想保持中断状态,可以再次调用interrupt方法设置中断状态。这样做的原因是,java的中断并不是真正的中断线程,而只设置标志位(中断位)来通知用户。如果你捕获到中断异常,说明当前线程已经被中断,不需要继续保持中断位。
interrupted是静态方法,返回的是当前线程的中断状态。例如,如果当前线程被中断(没有抛出中断异常,否则中断状态就会被清除),你调用interrupted方法,第一次会返回true。然后,当前线程的中断状态被方法内部清除了。第二次调用时就会返回false。如果你刚开始一直调用isInterrupted,则会一直返回true,除非中间线程的中断状态被其他操作清除了。

 

分享到:
评论

相关推荐

    java线程中的interrupt,isInterrupt,interrupted方法

    在 Java 中,线程(Thread)类提供了三个相关的方法:interrupt、isInterrupted 和 interrupted,这三个方法都是用于处理线程的中断状态的。下面我们将详细介绍这三个方法的用法和区别。 interrupt 方法 interrupt...

    Thread类的interrupt(),interrupted(),isInterrupted()1

    在Java多线程编程中,理解`Thread`类中的`interrupt()`、`interrupted()`和`isInterrupted()`方法至关重要,因为它们与线程中断机制紧密相关。线程中断是Java提供的一种协作式中断机制,它并不强制结束线程,而是...

    JAVA多线程之中断机制stop()、interrupted()、isInterrupted()

    在实际编程中,推荐使用`interrupt()`和`isInterrupted()`/`interrupted()`组合来实现线程的中断处理。例如,一个典型的线程循环可以这样编写: ```java while (!Thread.currentThread().isInterrupted()) { // ...

    Java中interrupt的使用.docx

    取而代之的是使用中断机制,这个机制主要通过`interrupt()`, `isInterrupted()`, 和 `interrupted()`三个方法来实现。 1. `interrupt()`方法:这个方法是用来设置目标线程的中断状态。当你在一个线程上调用另一个...

    线程中断的方法以及静态方法isInterrupted和实例方法interrupted的区别

    调用 interrupt() 方法来通知 通过共享的标记来实现中断 就是创建一个boolean类型的变量来控制循环是否进行,就是一个标记。 代码如下: /** * 描述:标记法中断线程 */ public class ThreadDemo { private static...

    浅谈Java线程Thread之interrupt中断解析

    需要注意的是,在使用interrupt机制时,需要注意线程的中断状态位的变化,避免使用Thread.interrupted()方法来判断线程是否被中断,因为该方法调用后会将中断标示位清除,即重新设置为false。 Java线程Thread之...

    java线程强制停止的两个Demo

    Java推荐使用更安全的中断机制,即通过`Thread.interrupt()`方法向线程发送中断信号,然后在线程的run方法中定期检查`isInterrupted()`或`interrupted()`状态来优雅地停止线程。这种方式允许线程清理资源并正常退出...

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

    Java提供了三种方法来实现多线程中断机制:`interrupt()`,`interrupted()`和`isInterrupted()`。这些方法都是Thread类中的方法,用于实现线程的中断机制。 1. `interrupt()`方法 `interrupt()`方法是用来中断某个...

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

    另一种是在适当的时候调用`Thread.interrupted()`或`isInterrupted()`来检查中断状态。`Thread.interrupted()`会返回当前线程的中断状态,并清除状态,而`isInterrupted()`仅检查状态,不会改变它。 值得注意的是,...

    java多线程之停止线程的方法实例代码详解

    总结以上所述,Java多线程之停止线程的方法实例代码详解可以使用退出标记、interrupt()方法和interrupted()方法来停止线程。使用退出标记停止线程简单易行,但需要对线程的执行过程进行控制。使用interrupt()方法和...

    java中断线程的正确姿势完整示例.rar

    在Java编程中,中断线程是一项重要的任务,特别是在多线程环境下,我们...通过正确使用`interrupt()`, `isInterrupted()`, 和`InterruptedException`,我们可以优雅地管理线程的生命周期,提高程序的稳定性和可维护性。

    java中 如何终止一个线程

    这是因为`Thread.interrupted()`会清除当前线程的中断状态,而`Thread.isInterrupted()`则只读取当前线程的中断状态而不进行清除。 2. **资源释放**:在处理中断时,还应考虑线程所使用的资源是否需要被释放。例如,...

    Java多线程教程吐血整理干货.md

    #### interrupt,interrupted,isInterrupted方法区别 - `interrupt`方法:用于标记当前线程为中断状态。这是一个标志位,用于指示线程是否已被请求中断。 - `interrupted`方法:返回当前线程是否已被中断,且会清除...

    thread-interrupt-test:显示线程中断行为的简单 Java 测试

    当调用`Thread.interrupt()`方法时,目标线程的`isInterrupted()`或`interrupted()`方法会返回`true`,表示线程被中断。这个标志可以用来中断阻塞操作,例如在`Thread.sleep()`, `Object.wait()`, 或者`java.nio....

    java多线程例子.doc

    接下来,我们关注线程的中断相关方法:`interrupt()`、`interrupted()`和`isInterrupted()`。`interrupt()`方法用于中断一个线程,设置线程的中断标志位。而`interrupted()`和`isInterrupted()`都是用来检查线程是否...

    Java中断一个线程操作示例

    Java提供了多种方式来中断一个线程,包括interrupt()、isInterrupted()和interrupted()函数。这些函数的使用技巧在实际开发中非常重要。 interrupt()函数是用于中断某个线程的方法,该函数的核心功能是将线程的中断...

    JUC学习.docx Java

    线程中常见的方法有`sleep`、`interrupt`、`isInterrupted`、`interrupted`、`park`、`yield`、`join`、`wait`和`notify`。`sleep`可以让线程进入等待状态,但不会释放锁。`interrupt`用于中断线程,尤其能打断`...

    java中的多线程笔记

    过调用 `t.interrupt()` 方法中断了 `t` 线程,而 `MyThread` 的 `run()` 方法中通过 `isInterrupted()` 检测中断状态,一旦检测到中断,循环就会停止,线程执行结束。这种方式保证了线程在接收到中断信号后能够优雅...

    JavaThread中断机制共11页.pdf.zip

    Java中的线程中断状态是一种标志,由`Thread.isInterrupted()`和`Thread.interrupted()`两个方法来检查和清除。`isInterrupted()`用于判断线程是否被中断,不会清除中断状态;而`interrupted()`不仅检查中断状态,...

Global site tag (gtag.js) - Google Analytics