为Thread编写一个舒适的暂停/停止方法

问题描述 投票:1回答:3

对于Java中的Thread子类,我试图编写一个方法checkPauseAndStop(),其目的是成为一个很好的单行程序,我可以在run()方法中定期调用以检查是否存在暂停/停止请求并相应地采取行动。

虽然功能齐全,但是通过InterruptedException处理停止线程,这会强制run() - 代码处于try-catch中并且感觉容易出错 (例如,Thread.sleep()不再告诉你它可能抛出这样的异常)。

是否有一种很好的方法可以在不影响run() - 方法的情况下处理方法内部停止线程?

代码示例:

public class SuspendableThread extends Thread
{
   private Semaphore lock = new Semaphore(1);
   public void checkPauseRequest() throws InterruptedException
    {
        if (isInterrupted())
            throw new InterruptedException();

        lock.acquire();
        lock.release();

    }

    @Override
    public void run()
    {
        try
        {
            while (true)
            {
                // Do_stuff
                checkPauseRequest();
            }

        }
        catch (InterruptedException e)
        {
            return;
        }
    }

当然,在这个特定的例子中,它根本不是必需的。为了获得更好的效果,想象一下我们有50个或更多的连续块

// Do_stuff
checkPauseRequest();

而不只是一个。

java multithreading java-threads
3个回答
1
投票

我会使用ScheduledExecutorService(你可以用Executors.newSingleThreadScheduledExecutor创建)和enum RunningState { RUNNING, PAUSED, STOPPED }来构建它。

虽然状态是RUNNING,但我们会继续安排延迟任务(使用ScheduledExecutorService.schedule)。每个任务检查我们是否仍然是RUNNING,如果是,则将单循环迭代排队(使用ExecutorService.submitExecutor.execute)。然后它为下一次迭代安排一个新的延迟任务(与Timer不同,你可以使用它来代替另一个线程)。

如果状态是PAUSED,我们会继续安排延迟任务以继续检查转换回RUNNING状态。但是我们没有为实际的循环迭代安排工作项。

如果状态是STOPPED,那么我们停止安排任何更多延迟的任务。

状态变量可以存储在一个简单的volatile字段中,该字段可以是静态的(如果只有这些东西中的一个)或者可以包含在代表“线程”的对象中(实际上它不再是单个线程) ,但可以类似于来电者的观点)。


1
投票

如果你想捕获发送到线程的中断,为了执行清理,你就无法将整个run()代码块放在try / catch异常块中。原因是如果你的线程正在执行任何类型的线程间信令,通过条件变量或信号量例如(调用wait()方法),你的run()代码块将立即抛出一个InterruptedException,如果中断状态标志为线程设置。但是,如果你想主动检查你的线程的中断状态,最简单的方法是喷一堆中断点,也就是你的checkPause()方法,然后放几纳秒的睡眠(你的sleep()方法会抛出如果设置了中断标志,则为InterruptedException。这样可以在不影响线程性能的情况下实现您的目标。


0
投票

请确保你想要实现的目标真正有意义并且不会让我们重新发明轮子类别。制作任何通用的“一刀切”停止方法并不是一件容易的事,尽管它对Java创建者来说也是如此。这就是弃用Thread.stop()方法的原因。 (https://docs.oracle.com/javase/10/docs/api/java/lang/Thread.html#stop())(和Thread.destroy()实际上没有实现AFAICT。)

有一个非常好的解释:https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

© www.soinside.com 2019 - 2024. All rights reserved.