Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为线程编写舒适的暂停/停止方法_Java_Multithreading_Java Threads - Fatal编程技术网

Java 为线程编写舒适的暂停/停止方法

Java 为线程编写舒适的暂停/停止方法,java,multithreading,java-threads,Java,Multithreading,Java Threads,对于Java中的一个线程子类,我试图编写一个方法checkPauseAndStop(),它的目的是作为一个好的线性函数,我可以在run()方法中定期调用它来检查是否有暂停/停止请求,并相应地采取行动 在完全正常的情况下,停止线程是通过InterruptedException来处理的,这会强制run()-代码处于try-catch状态,并且感觉容易出错(例如,thread.sleep()不再告诉您它可能抛出这样的异常) 有没有什么好方法可以在不妨碍run()方法的情况下在方法内部停止线程 代码示例

对于Java中的一个线程子类,我试图编写一个方法
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();

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

请确保您尝试实现的目标真正有意义,并且不属于“让我们重新发明轮子”类别。制作任何通用的“一刀切”停止方法并不是一件小事,尽管对Java创建者来说也是如此。这就是为什么Thread.stop()方法被弃用的原因。()(Thread.destroy()实际上并没有在AICT中实现。)


这里有一个很好的解释:.

我将使用一个
ScheduledExecutorService
(可以使用
Executors.newSingleThreadScheduledExecutor
创建)和一个
枚举运行状态{RUNNING,pause,STOPPED}

当状态
正在运行时
,我们会继续调度延迟的任务(使用
ScheduledExecutorService.schedule
)。每个任务都会检查是否仍在运行
,如果仍在运行,则将单个循环迭代排队(使用
ExecutorService.submit
Executor.execute
)。然后,它为下一次迭代安排一个新的延迟任务(与
计时器不同,您可以使用它来代替,但代价是另一个线程)

如果状态为“暂停”
,我们将继续安排延迟的任务,以检查是否转换回“运行”
状态。但是我们没有为实际的循环迭代安排工作项

如果状态为“已停止”
,则我们停止调度任何更多延迟的任务


状态变量可以存储在一个简单的
volatile
字段中,该字段可以是静态的(如果只有其中一个),也可以封装在一个表示“线程”的对象中(实际上不再是单个线程,但从调用方的角度来看,它可以类似于一个线程)。一个简单的共享
AtomicBoolean shouldStop
可能足以返回,而无需使用InterruptedException。无论采用哪种方式,您都必须决定循环中应将
checkPauseRequest()
放置在何处。无论是1次还是多次,任何有意义的事情都能在某个单元工作后暂停/停止。考虑使用<代码>信号量< /代码>,而不是使用<代码>锁定< /代码>。原因就是,。当其他程序员看到一个
锁时
,他们通常希望它用于互斥;但是当他们看到一个
信号量时,他们希望它用于线程之间的信令。如果您使用
发送信号,可能会给其他程序员留下这样的印象,即您的编码风格“怪异”,而且可能不可信。@AndrewS我并没有真正理解您的论证。
AtomicBoolean
除了作为
Semaphore
的替代品之外,还有什么帮助呢?
AtomicBoolean
是一个能够优雅地退出线程的例子,而不是捕获
interruptedexception
并从捕获中返回
Semaphonre
仍然可以暂停线程。@AndrewS我不知道,除了使用异常之外,我如何可以向后跳转多个作用域(除了为每个作用域调用run一次以退出)OP使用了“停止”这个词,但是
t.stop()
做了一些与OP要求的非常不同的事情。在<代码> STORE()/SCOD>调用的接收端上的线程没有任何发言权:任何其他线程都可以随时调用<代码> THT()(或代码>),如果发生在一些重要的数据结构的中间,则没有线程<代码> t>代码>可以进行清理。另一方面,OP所要求的是线程
t
在安全点检查它是否被要求暂停或停止的一种干净的方式。@besmirched,这就是为什么我包含了一个到教程的链接,描述如何使用中断。;-)虽然没有严格地提到这个问题,但我经常看到人们试图用Java实现“思想中的线程模型”,而不是使用Java中实际存在的线程模型。当然,我也在使用Java的monito实现信号量