• java线程中断Interrupted用法


    停止一个线程的主要机制是中断,中断并不代表强迫终止一个线程,

    它是一种协作机制,是给线程传递一个取消的信号,

    但是让线程来决定如何以及何时退出。

    这句话可谓是线程中断的核心原理了;光看文字还是很模糊的,用代码说事吧。

     1 public class ThreadEnd implements Runnable {
     2 
     3     private volatile static boolean ok=false;
     4     @Override
     5     public void run() {
     6        for(;;){
     7             if(Thread.currentThread().isInterrupted()){
     8                 System.out.println("我进入了中断线程的条件中,将要结束run方法");
     9                 break;//因为是for死循环,用这种方式退出循环
    10             }else{
    11                 System.out.println("我没有收到中断信息");
    12             }
    13         }
    14     }
    15 
    16 
    17 
    18     public static void main(String[] args) throws InterruptedException {
    19         Thread thread = new Thread(new ThreadEnd());
    20         thread.start();
    21         Thread.sleep(1000);
    22         thread.interrupt();
    23         System.out.println("主线程结束");
    24 
    25     }
    26 }

    在第6行中不停的死循环来查看线程 isInterrupted()方法是否返回true;

    第22行代码给线程调用了线程中断方法,第7行条件满足,最终退出线程。

    那么有一个疑问:是不是所有的线程都可以用interrupt()方法进行中断呢?

    比如说sleep的线程,比如说等待锁的线程?我们挨个来求解吧。

    sleep休眠线程中断代码

     1 public class InterruptionSleepThread implements Runnable {
     2 
     3     @Override
     4     public void run() {
     5         try {
     6             System.out.println("本大爷要休眠50秒,你能奈我何?");
     7             Thread.sleep(50000);//休眠50秒
     8         } catch (InterruptedException e) {
     9             System.out.println("休眠的线程收到中断信号,利用抛异常的方式将本大爷从梦中叫醒,结束线程。");
    10             e.printStackTrace();
    11         }
    12     }
    13     public static void main(String[] args) throws InterruptedException {
    14         Thread thread = new Thread(new InterruptionSleepThread());
    15         thread.start();
    16         Thread.sleep(2000);
    17         thread.interrupt();
    18         System.out.println("主线程结束");
    19 
    20     }
    21 }

    打印结果

    从上面的打印结果来看,休眠的线程是的确退出来了,虽然这个叫醒的方式不怎么优雅(异常的方式)。

    这也从另外一个角度告诉了我们,为什么每次在run()里面调用sleep()方法的时候,编译器要我们强制进行异常捕获了,也是为了程序安全。

    等待锁的过程中,被中断的代码

     1 public class WaitLockThreadInterrupted extends Thread {
     2 
     3     private static Object lock =new Object();
     4 
     5     @Override
     6     public  void run() {
     7         System.out.println("我要等待test锁释放后,才能执行下面的代码");
     8         synchronized (lock){
     9           while (true){
    10               if(Thread.currentThread().isInterrupted()){
    11                   System.out.println("我收到线程中断的信号");
    12                   break;
    13               }else{
    14                   System.out.println("没收到线程中断的信号");
    15               }
    16           }
    17         }
    18     }
    19 
    20     private static void test() throws InterruptedException {
    21         synchronized (lock){
    22             Thread thread=new Thread(new WaitLockThreadInterrupted());
    23             thread.start();
    24             Thread.sleep(1000);
    25             thread.interrupt();
    26             System.out.println("已发出中断信号");
    27             thread.join();//阻塞test方法,一直到线程thread执行完毕。
    28         }
    29     }
    30 
    31     public static void main(String[] args) throws InterruptedException {
    32       test();
    33     }
    34 }

    打印结果

    虽然打印了结果,但是左边的红灯一直亮着,并且也没有打印11行的内容,表示线程一直没有退出来。

    分析代码:test中的synchronized()和run方法中的synchronized用了同一个对象锁,

    所以22行的thread线程中的run方法的执行,必须等到test释放掉lock锁对象才行;

    但是 test中用thread.join()方法来告诉我们,等thread线程执行完毕了,我才能放你们走。

    完了,死锁了。

    这种死锁的状态如果25行代码发出中断信号有用的话,这种死锁的尴尬是能够解开的。

    从打印结果来看 interrupt()是不能中断等待锁的线程的。

    结论:

    1.Runnable状态(正在运行或者等待调度的线程)可以用interrupt()中断

    2.Block状态(等待锁的线程)不可以用interrupt()中断

  • 相关阅读:
    nyoj-68-三点顺序-计算几何
    zoj--1089--Lotto---DFS VS 暴力求解
    zoj----1090---The Circumference of the Circle---数学几何
    nyoj-阶乘0
    nyoj-回文字符串--动态规划
    nyoj-最长公共子序列---动态规划
    hdu-1285确定比赛名次---拓扑排序
    等式数量---hash算法
    学生学籍管理系统
    2020.2.9 解决Zabbix agent is not available&windows下安装zabbix-agent 主机部署监控
  • 原文地址:https://www.cnblogs.com/guoyansi19900907/p/12585601.html
Copyright © 2020-2023  润新知