Thread Interrupt详解

线程interrupt

interrupt

如下方法的调用会使得线程进入阻塞状态,而调用当前线程的interrupt方法,可以打断阻塞。

Object的wait,Thread的sleep,Thread的join,InterruptibleChannel的io操作 等等

若当前线程在阻塞的状态,另外一个线程调用被阻塞线程的interrupt方法,则会打断这种阻塞,因此这种方法有时候可被称为可中断方法。

一旦线程在阻塞的情况下被打断,都会抛出一个称为InterruptedException的异常,这个异常就像一个Signal(信号)通知当前线程被打断

public class ThreadInterrupt{
	public static void main(String[] args) throws InterruptedException{
    Thread thread = new Thread(()->{
      try{
        TimeUnit.MINUTES.sleep(1);
      } catch(InterruptedException e){
        sout("Oh i am be interrupted");
      }
    });
    thread .start();
    TimeUnit.MILLISECONDS.sleep(2);
    thread.interrupt();
  }
}

上面的代码创建了一个线程,并且企图休眠1分钟的时长,但大约两秒之后就会被主线程调用interrupt方法打断。输出”i am be interrupted"

为啥,因为在线程内部有一个Interrupted flag,如果一个线程被interrupt,那么它的flag将被设置,但是如果当前线程正在执行可中断方法被阻塞时,调用interrupt方法将其中断,反而会导致flag被清除,负负得正,如果线程已经死亡,尝试对其interrupt会被直接忽略。

isInterrupted

isInterrupted 是Thread的一个成员方法,它主要判断当前线程是否被中断,该方法仅仅是对interrupted标识的一个判断,并不会影响标识发生任何改变。

public class ThreadisInterrupted{
	public static void main(String[] args) throws InterruptedException
	{
	Thread thread = new Thread()
  {
    public void run()
    {
      while(true){
        // do nothing,just empty loop
      }
    }
  };
    thread.start();
    TimeUnit.MILLISECONDS.sleep(2);
    souf("Thread is interrupted ? %s\n",thread.isInterrupted());
    thread.interrupt();
    souf("Thread is interrupted ? %s\n",thread.isInterrupted());
	}
}

结果为

Thread is interrupted ? false;

Thread is interrupted ? true;

如果是可中断方法,会擦除Interrupted标识,为啥?因为不影响线程中其他方法的执行。

Interrupted

interrupted是一个静态方法,虽然其也用于判断当前线程是否可被中断,但是它和成员方法isInterrupted还是有很大区别的,调用该方法会直接擦除掉线程的interrupt标识,需要注意的是,如果当前线程被打断了,第一次掉用会返回true;第二次包括以后的调用永远都会返回false

interrupt注意事项

isInterrupted方法和interrupted方法都调用了同一个本地方法

private native boolean isInterrupted(boolean ClearInterrupted)

public boolean isInterrupted(){
return isInterrupted(false);
}
public static boolean interrupted(){
  return currentThread().isInterrupted(true);
}
 public static void main(String[] args) {
        System.out.println("Main thread is interrupted? " +Thread.interrupted());
        Thread.currentThread().interrupt();
        System.out.println("Main thread is interrupted? " +Thread.currentThread().isInterrupted());
        try{
            TimeUnit.MINUTES.sleep(1);
        }catch (InterruptedException e){
            System.out.println("i will be interrupted still.");
        }
    }

文章参考自《Java高并发编程详解》

posted @ 2023-03-19 12:43  meta-treasure  阅读(138)  评论(0编辑  收藏  举报