博客
关于我
java更加优雅并且主动控制线程中断
阅读量:786 次
发布时间:2019-03-25

本文共 2880 字,大约阅读时间需要 9 分钟。

一、stop()方法

提到中断线程,首先想到的可能是stop()方法。然而,这个方法已被官方退化为不推荐使用。以下是官方给出的原因:

  • 停止执行:调用stop()方法会立即停止run()方法中剩余的所有工作,包括catch或finally语句中的内容,并抛出ThreadDeath异常。这种异常通常情况下不需要显式捕获,可能导致文件、数据库等资源未能完成正确关闭。

  • 锁定问题:stop()方法立即释放线程所持有的所有锁定,导致数据同步错误,可能造成数据不一致。

  • 因此,我们不能使用stop()方法来中断线程。


    二、interrupt()方法

    使用interrupt()方法能否中断线程?答案是否定的。

    interrupt()方法只是设置线程的一个标志,便通知线程可以中断,但实际中断时机由线程自己决定。

    以下是通过一个简单示例来理解:

    public class InterruptedTask implements Runnable {    @Override    public void run() {        Thread currentThread = Thread.currentThread();        while (true) {            if (currentThread.isInterrupted()) {                break;            }            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();                // 在这里,我们需要重新设置中断标记                currentThread.interrupt();            }        }    }}public class InterruptedTest {    public static void main(String[] args) {        InterruptedTask task = new InterruptedTask();        Thread thread = new Thread(task);        thread.start();        try {            Thread.sleep(1000);        } catch (InterruptedException e) {            e.printStackTrace();        }        thread.interrupt();    }}

    运行结果显示,线程并未退出。这是因为:

    • InterruptedException异常:Thread.sleep()方法会在被中断时抛出InterruptedException异常。
    • JVM在抛出异常时会重置线程的中断标记(currentThread.isInterrupted()返回false),导致线程无法再次受中断影响。

    要正确中断线程,必须在捕获异常后重新设置中断标记:

    public class InterruptedTask implements Runnable {    @Override    public void run() {        Thread currentThread = Thread.currentThread();        while (true) {            if (currentThread.isInterrupted()) {                break;            }            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();                // 重新设置中断标记                currentThread.interrupt();            }        }    }}

    三、标志位中断线程

    为了更好地控制线程的中断,可以使用自定义标志位。例如,在服务器程序中,线程可能进入一个持续接收客户端请求的循环,使用标志位来终止线程:

    public class ServerThread extends Thread {    public volatile boolean exit = false; // 保证多线程环境下读取最新值    @Override    public void run() {        ServerSocket serverSocket = new ServerSocket(8080);        while (!exit) {            try {                Socket socket = serverSocket.accept();                // 处理客户端请求                socket.close();            } catch (IOException e) {                // 处理socket异常            }        }    }    public static void main(String[] args) {        ServerThread server = new ServerThread();        server.start();        try {            // 做一些运算            Thread.sleep(1000);        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            server.exit = true; // 设置标志位终止线程        }    }}

    在这种方式下,我们可以主动控制线程何时中断,适用于需要定制化控制的场景。


    总结

    中断线程的方法有三个:

  • 已弃用的stop()方法。
  • 通过interrupt()设置中断标记,但线程中断由运行环境决定。
  • 使用自定义标志位主动控制线程终止。
  • 根据需求选择合适的方法是关键。标志位方法提供了更高的灵活性,适合主动控制线程终止的情况。

    转载地址:http://sbsuk.baihongyu.com/

    你可能感兴趣的文章
    SpringBoot中集成SpringBatch详细解析与实战示例(CSV文件读取十万条数据进行业务处理后写入Mysql数据库)
    查看>>
    powerbi 一张表在另外一张表中出现的数量_PowerBi之初步学习笔记
    查看>>
    QGIS怎样设置简体中文以及新建可编辑的多边形的图层
    查看>>
    PowerBuilder 使用自定义事件触发键盘Enter事件
    查看>>
    PowerCreatorCMS UploadResourcePic 任意文件上传漏洞复现
    查看>>
    PowerDesigner 使用的一些技巧(转)
    查看>>
    QGIS在Windows上下载安装与建立空间数据库连接
    查看>>
    PowerDesigner165安装婆姐汉花教程
    查看>>
    PowerDesigner使用教程:设置注释、默认值属性
    查看>>
    PowerDesigner使用教程:不显示背景网格
    查看>>
    PowerDesigner使用教程:创建数据模型以及导出
    查看>>
    PowerDesigner使用教程:右侧工具栏显示/隐藏
    查看>>
    PowerDesigner使用教程:导出sql文件以及解决中文乱码问题
    查看>>
    PowerDesigner使用教程:时间字段设置
    查看>>
    PowerDesigner使用教程:给字段添加唯一约束
    查看>>
    QGIS中怎样设置图层样式并导出地图样式
    查看>>
    PowerDesigner使用笔记
    查看>>
    QGIS中怎样实现数据坐标系转换
    查看>>
    PowerDesigner学习--基本步骤
    查看>>
    PowerDesigner导出Report通用报表
    查看>>