博客
关于我
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/

    你可能感兴趣的文章
    POJ1218 HDU1337 ZOJ1350 UVALive2557 THE DRUNK JAILER
    查看>>
    poj1222 EXTENDED LIGHTS OUT(gauss)
    查看>>
    POJ1240 m叉树
    查看>>
    Poj1328--Radar Installation(区间选点)
    查看>>
    POJ1384Piggy-Bank(DP)
    查看>>
    POJ1417 True Liars —— 并查集 + DP
    查看>>
    Poj1459 Power Network 预流推进
    查看>>
    POJ1502(MPI Maelstrom)
    查看>>
    poj1568 Find the Winning Move[极大极小搜索+alpha-beta剪枝]
    查看>>
    poj1730 - Perfect Pth Powers(完全平方数)(水题)
    查看>>
    poj1753——Flip Game
    查看>>
    poj1936 假期计划第一水
    查看>>
    poj1958-汉诺四塔问题(三种方法)
    查看>>
    poj1988(并查集)
    查看>>
    POJ2007+几何+极角排序
    查看>>
    poj2039
    查看>>
    poj2135(简单的最小费用流问题)
    查看>>
    poj2195 bfs+最小权匹配
    查看>>
    POJ2251
    查看>>
    POJ2253-Frogger
    查看>>