线程一1.0 线程的interrupt()、interrupted()和isInterrupted()。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/insis_mo/article/details/88393834

一  interrupt  :

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

object的wait 方法

thread的sleep 方法

thread的join方法

interruptiblechannel的io操作

selector的wakeup方法

其他方法

上述若干方法都会是线程进入阻塞状态,若另外一个线程调用阻塞线程的interrupt方法,则会打断这个阻塞,因此可以称为可中断方法,打断一个线程并不等于该线程的生命周期结束,仅仅是打断了当前线程的阻塞状态,

  一旦线程在阻塞的情况下被打断都会抛出一个interruptedExcption 的异常,这个异常就像一个signal信号),一样通知当前线程被打断了,如下:

public class ThreadPriority {
public static void main(String[] args) throws InterruptedException {
    Thread thread=new Thread(() ->{
        try {
            TimeUnit.MINUTES.sleep(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            System.out.println("i am be interrupted");
        }
    });
    thread.start();
    TimeUnit.MILLISECONDS.sleep(2);
    thread.interrupt();
}
}
上面的代码创建一个线程,并且企图偷懒一分钟。不过可惜大约在几毫秒之后被主线程调用interrupt方法打断,程序执行结果就是 i am be interrupted、

   interrupt方法做了什么呢?在一个线程内部存在名为interrupt flag  的标识,如果一个线程被interrupt ,那么他的flag将被设置,但是如果当前线程正在执行可中断方法被阻塞时,调用interrupt方法将其中断,反而会导致flag被清除,,如果一个线程已经是死亡状态,那么尝试对其的interrupt 会直接被忽略

isinterrupted 

isinterrupted  是thread类的一个成员方法,它主要判断当前线程是否被中断,该方法仅仅是对interrupt标识的一个判断,并不会影响标识发生任何改变,看一个例子:

public class ThreadPriority {
public static void main(String[] args) throws InterruptedException {
    Thread thread=new Thread() {
        @Override
        public void run() {
            while(true) {
                
            }
        }
        
    };
    thread.start();
    TimeUnit.MILLISECONDS.sleep(2);
    System.out.printf("there is interrupted?%s\n",thread.isInterrupted());
    thread.interrupt();
    System.out.printf("there is interrupted?%s\n",thread.isInterrupted());
}
}

结果:

there is interrupted?false
there is interrupted?true
上面代码中定义了一个线程,并且在线程执行单员中写了一个空的死循环,为什么不写sleep呢? 因为sleep 是一个可中断方法,会捕获到中断信号,从而干扰到我们程序的结果,,可中断方法捕获到中断信号(signal)之后也就是捕获了interruptException 异常之后会擦除掉interrupt 的标识,对上面的程序稍作修改,如下:

public class ThreadPriority {
public static void main(String[] args) throws InterruptedException {
    Thread thread=new Thread() {
        @Override
        public void run() {
        try {
            TimeUnit.MINUTES.sleep(1);
        } catch (InterruptedException e) {
            System.out.printf("i am be interrupt ? %s\n",isInterrupted() );
        }
        }
        
    };
    thread.setDaemon(true);
    thread.start();
    TimeUnit.MILLISECONDS.sleep(2);
    System.out.printf("there is interrupted?%s\n",thread.isInterrupted());
    thread.interrupt();
    TimeUnit.MILLISECONDS.sleep(2);
    System.out.printf("there is interrupted?%s\n",thread.isInterrupted());
}
}
结果:、

there is interrupted?false
i am be interrupt ? false
there is interrupted?false

由于在run 方法中使用了sleep这个可中断方法,他会捕获到中断信号,并且会擦除interrupt 标识,因此执行结果会是flase, 

当中断方法捕获到了中断信号之后,为了不影响线程中其他方法的执行,将线程的interrupt标识复位,

interrupted

interrupted 是一个静态方法,虽然其也用于判断当前线程是否被中断,但是和isinterrupted是有很大区别的,调用该方法会直接擦除interrupt 标识,需要注意的是 ,如果当前线程被打断了,那么第一次调用interrupted返回true,并且立即擦除interrupt标识,第二次包括以后都会返回false,除非在此期间,线程又一次被打断,例如:

public class ThreadPriority {
public static void main(String[] args) throws InterruptedException {
    Thread thread=new Thread() {
        @Override
        public void run() {
            while(true) {
                System.out.println(Thread.interrupted());
            }
        }
        
    };
    thread.setDaemon(true);
    thread.start();
    TimeUnit.MILLISECONDS.sleep(2);
//    System.out.printf("there is interrupted?%s\n",thread.isInterrupted());
    thread.interrupt();
//    TimeUnit.MILLISECONDS.sleep(2);
//    System.out.printf("there is interrupted?%s\n",thread.isInterrupted());
}
}

同样由于不想受到可中断方法如sleep的影响,在run方法中没有进行休眠,

结果:

很多false中有一个true,也就是interrupted方法判断到了他被中断,立即擦除了中断标识,后面都是false

猜你喜欢

转载自blog.csdn.net/insis_mo/article/details/88393834