怎么关闭一个 Java 线程 ( Thread ) ?

yufei       6 年, 1 月 前       844

怎么关闭一个 Java 线程 ( Thread ) ? 噢,不,正确的问题是怎么正确的关闭一个 Java 线程?

这个问题是不是很简单? 很简单啊,不就是使用 Thread.stop() 方法么?

但是,根据 ORACLE 的更新文档Thread.stop() 方法可能导致监视器对象被破坏。

因此,我们必须使用其它更安全的方法,或在 Thread.stop() 方法上做一些改变。

使用一个标志 ( Flag )

假设存在一个任务,这个任务并不会自己自动结束,因此我们必须找到一些方式来停止该线程。

为了方便你的理解,我们从创建和启动线程的类开始,一步一步讲解。

首先,我们需要一个原子性的标志 ( flag )

public class ControlSubThread implements Runnable {

    private Thread worker;
    private final AtomicBoolean running = new AtomicBoolean(false);
    private int interval;

    public ControlSubThread(int sleepInterval) {
        interval = sleepInterval;
    }

    public void start() {
        worker = new Thread(this);
        worker.start();
    }

    public void stop() {
        running.set(false);
    }

    public void run() { 
        running.set(true);
        while (running.get()) {
            try { 
                Thread.sleep(interval); 
            } catch (InterruptedException e){ 
                Thread.currentThread().interrupt();
                System.out.println(
                  "Thread was interrupted, Failed to complete operation");
            }
            // do something here 
         } 
    } 
}

上面这段代码中,我们使用了 AtomicBoolean 而不是让 while 循环评估常量 true。

有了这个标志,我们就可以通过将其设置为 true/false 来启动/停止执行。

中断线程

当把 sleep() 设置为较长的间隔时,或者我们正在等待可能永远不会被释放的 时会发生什么 ?

我们面临长期阻塞或永不干净的风险。

为了解决这类问题,我们可以创建一个 interrupt()

为了演示如何创建 interrupt() ,我们在刚刚的范例基础上添加一些方法和一个新标志。

public class ControlSubThread implements Runnable {

    private Thread worker;
    private AtomicBoolean running = new AtomicBoolean(false);
    private int interval;

    // ...

    public void interrupt() {
        running.set(false);
        worker.interrupt();
    }

    boolean isRunning() {
        return running.get();
    }

    boolean isStopped() {
        return stopped.get();
    }

    public void run() {
        running.set(true);
        while (running.get()) {
            try {
                Thread.sleep(interval);
            } catch (InterruptedException e){
                Thread.currentThread().interrupt();
                System.out.println(
                  "Thread was interrupted, Failed to complete operation");
            }
            // do something
        }
    }
}

上面这段代码中,我们添加了一个 interrupt() 方法,并在该方法中将运行标志设置为 false ,然后调用工作线程的 interrupt() 方法中断线程。

如果线程在调用此函数时处于休眠状态,则 sleep() 会退出并抛出一个 InterruptedException 异常,就像任何其它阻塞调用一样。

后记

哎,本来可以使用 Thread.stop() 解决的问题,结果为了考虑锁和监视器,整蛊了一个长的解决方案,这难道就是 Java 开发不能避免的?

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.