zoukankan      html  css  js  c++  java
  • Java学习-082-多线程15:线程中断退出

    查看上篇文章的源代码执行结果,可以发现,在中断线程后,线程状态并未变化,且线程并未立即停止运行,而是继续运行至结束,输出创建了 800 个文件。

    查看 Thread.interrupt() 源代码可知,interrupt() 中断线程方法,仅设置线程的中断标志位为 true 并立即返回,并未改变线程运行状态。源代码如下所示:

    通过 isInterrupted() 方法,可以查看当前线程是否被中断,进而通过代码逻辑控制决定是否停止线程操作。isInterrupted() 源代码如下所示。

    通过 interrupted()  方法,也可查看当前线程是否被中断,进而通过代码逻辑逻辑实现业务需求。但与 isInterrupted()  不同的是,interrupted() 该方法发现线程中断后会清空线程中断标志。 

    因而,在判定线程是否被中断时,推荐使用 isInterrupted() 方法。

    使用 isInterrupted()  方法处理线程被中断后的业务操作逻辑实现代码如下所示:

    package com.fanfengping.demo;
    
    import lombok.extern.slf4j.Slf4j;
    
    import java.io.*;
    
    @Slf4j
    public class Demo10RunnableInterruptExit implements Runnable {
        @Override
        public synchronized void run() {
            Thread thread = Thread.currentThread();
    
            try {
                log.info("t1 >> {} 开始运行", thread.getName());
                log.info("t2 >> {} 运行状态:{},是否存活:{},是否被中断:{}", thread.getName(), thread.getState().name(), thread.isAlive(), thread.isInterrupted());
    
                log.info("t3 >> {} 开始休眠", thread.getName());
                Thread.sleep(3000);
                log.info("t4 >> {} 结束休眠", thread.getName());
    
                log.info("t5 >> {} 开始写文件", thread.getName());
                for (int i = 0; i < 800; i++) {
                    // 若是线程被中断,则退出线程
                    if(!Thread.currentThread().isInterrupted()) {
                        File file=new File("E:/office-new/personal/multi-thread-demo/src/main/resources/files/test-" + i + ".log");
                        if(!file.exists())
                            file.createNewFile();
                        FileOutputStream out = new FileOutputStream(file,true);
                        for(int j=0;j<10000;j++) {
                            StringBuffer sb = new StringBuffer();
                            sb.append("这是第"+i+"行:前面介绍的各种方法都不关用,为什么总是奇怪的问题 ");
                            out.write(sb.toString().getBytes("utf-8"));
                        }
                        out.close();
                    } else {
                        break;
                    }
                }
                log.info("t6 >> {} 结束写文件", thread.getName());
    
                log.info("t7 >> {} 开始休眠", thread.getName());
                Thread.sleep(5000);
                log.info("t8 >> {} 结束休眠", thread.getName());
            } catch (InterruptedException | UnsupportedEncodingException e) {
                log.error("t9 >> " + thread.getName() + " 被中断", e);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            try {
                Demo10RunnableInterruptExit demo10RunnableInterrupt = new Demo10RunnableInterruptExit();
    
                Thread threadInterrupt = new Thread(demo10RunnableInterrupt, "Interrupt_demo");
    
                log.info("1 >> {} 运行状态:{},是否存活:{},是否被中断:{}", threadInterrupt.getName(), threadInterrupt.getState().name(), threadInterrupt.isAlive(), threadInterrupt.isInterrupted());
    
                log.info("2 >> {} 启动线程", threadInterrupt.getName());
                threadInterrupt.start();
                log.info("3 >> 主线程休眠 1 秒");
                Thread.sleep(1000);
                log.info("4 >> {} 运行状态:{},是否存活:{},是否被中断:{}", threadInterrupt.getName(), threadInterrupt.getState().name(), threadInterrupt.isAlive(), threadInterrupt.isInterrupted());
    
                log.info("5 >> 主线程休眠 7 秒");
                Thread.sleep(7000);
                log.info("6 >> {} 中断线程", threadInterrupt.getName());
                threadInterrupt.interrupt();
                log.info("7 >> 主线程休眠 1 秒");
                Thread.sleep(1000);
                log.info("8 >> {} 运行状态:{},是否存活:{},是否被中断:{}", threadInterrupt.getName(), threadInterrupt.getState().name(), threadInterrupt.isAlive(), threadInterrupt.isInterrupted());
    
                log.info("9 >> 主线程休眠 18 秒");
                Thread.sleep(18000);
                log.info("10 >> {} 运行状态:{},是否存活:{},是否被中断:{}", threadInterrupt.getName(), threadInterrupt.getState().name(), threadInterrupt.isAlive(), threadInterrupt.isInterrupted());
    
                log.info("11 >> 主线程休眠 40 秒");
                Thread.sleep(40000);
                log.info("12 >> {} 运行状态:{},是否存活:{},是否被中断:{}", threadInterrupt.getName(), threadInterrupt.getState().name(), threadInterrupt.isAlive(), threadInterrupt.isInterrupted());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

     执行结果如下图所示:

    在执行业务逻辑代码外围,添加方法判断逻辑控制。执行源代码可以发现,核心业务(创建文件)在线程中断后,停止运行。实际操作中,也可根据实际需求对已处理的业务逻辑进行回滚处理,以保证中断前后数据的一致性。

    我本渺小,但山峰,我一次次绝顶!


    PS:若有错误,敬请告知,不胜感激!
    Copyright @范丰平 版权所有,如需转载请标明本文原始链接出处,严禁商业用途! 我的个人博客链接地址:http://www.cnblogs.com/fengpingfan
  • 相关阅读:
    jquery datatable[表格处理]之AdminLTE
    kdevtmpfsi挖矿病毒导致服务器cpu高负荷运行
    Python3 '%Y-%m-%dT%H:%M:%S.000Z' 时间格式转换
    python-生成动态路由轨迹图(scapy模块)
    Python之XlsxWriter模块(数据报表)
    python之web服务质量探测(pycurl模块)
    Django-图片验证码
    最简容器化动手小实践——再战flappybird
    基于OAS设计可扩展OpenAPI
    Istio最佳实践:在K8s上通过Istio服务网格进行灰度发布
  • 原文地址:https://www.cnblogs.com/fengpingfan/p/14739156.html
Copyright © 2011-2022 走看看