• Java并发编程的艺术(六)——中断、安全停止线程


    什么是中断

    Java的一种机制,用于一个线程去暂停另一个线程的运行。就是一个正在运行的线程被其他线程给打断,停止运行挂起了。

    我觉得,在Java中,这种中断机制只是一种方便程序员编写进程间的通信罢了。

    如何中断

    • interrupt()
      其他线程调用这一线程的这一方法来对其进程中断。
    • isInterrupted()
      当前线程通过这个方法来判断自己是否被中断了。
    • interrupted()
      调用静态方法对当前线程的中断标识进行复位

    中断实现原理

    中断的执行流程逻辑需要程序员自己完成。

    • 每个线程对象都具有一个中断标识属性,用于表示该线程是否被中断了,ture代表中断,false代表没有中断。
    • 通过调用目标线程的interrupt()方法将该线程的中断表示设置为true;可以由任意线程调用。
    • 被中断线程不断通过条用interrupted() 方法判断自己是不是被中断了,如果被中断了,执行何种逻辑需要程序员自己完成。

    中断使用

    如果需要使用中断,那么被中断的线程得不断监听中断状态,如果状态发生改变,就执行相应的处理逻辑。

    设置中断监听

    Thread t1 = new Thread( new Runnable(){
        public void run(){
            // 若未发生中断,就正常执行任务
            while(!Thread.currentThread.isInterrupted()){
                // 正常任务代码
            }
    
            // 中断的处理代码
            doSomething();
        }
    } ).start();
    

    触发中断

    t1.interrupt();
    

    可以有当前线程调用,也可以由其他线程调用。

    安全停止线程

    过时了的stop方法过于暴力,它虽然能够立即停止线程,但是不能保证线程能够正常释放资源,没给机会。所以需要安全地停止线程,有其他方法。

    循环中断方法

    已经在上面介绍

    循环标记变量

    自定义一个共享地Boolean类型用于表示线程是否需要中断。

    volatile boolean interrupted = false;
    
    Thread t1 = new Thread( new Runnable(){
        public void run(){
            while(!interrupted){
                // 正常任务代码……
            }
            // 中断处理代码……
            // 可以在这里进行资源的释放等操作……
        }
    } );
    
    // 中断函数
    Thread t2 = new Thread( new Runnable(){
        public void run(){
            interrupted = true;
        }
    } );
    

    总结

    其实上述两种方法本质都是一样的,都是通过一个标志位来实现进程间的通信,在线程可控可见的方式下,友好地暂停对方,这样就可以在程序员可控的地方释放资源什么的。

    处理中断

    当线程接受到中断信号,需要如何处理。

    • 如果目标线程运行太久了,不想等待了,就用其他线程去中断它。
    • 当你在某一条线程中调用这些方法时,这个方法可能会被阻塞很长时间,你可以在别的线程中调用当前线程对象的interrupt方法触发这些函数抛出InterruptedException异常。
    • 当你捕获到InterruptedException异常后,当前线程的中断状态已经被修改为false(表示线程未被中断);此时你若能够处理中断,则不用理会该值;但如果你继续向上抛InterruptedException异常,你需要再次调用interrupt方法,将当前线程的中断状态设为true
    • 当捕获到InterruptedException异常的时候,可以处理,也可以向上抛出。
    • 不能忽视InterruptedException异常。
  • 相关阅读:
    webservice底层使用Socket进行网络调用
    jquery事件绑定
    C#连接PostgreSQL查询中文字符出现乱码情况
    Engine加载ArcGIS Online和ArcGIS Server发布的地图服务
    【转载】MFC中tabcontrol控件的使用
    一、VS2010创建一个MFC项目
    二、VS2012配置OpenCV
    三、编译和配置GDAL
    Python调用百度地图API(路线规划、POI检索)
    【转载】Python操作Excel的读取以及写入
  • 原文地址:https://www.cnblogs.com/lippon/p/14117668.html
Copyright © 2020-2023  润新知