代码之家  ›  专栏  ›  技术社区  ›  Sudix

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

  •  1
  • Sudix  · 技术社区  · 6 年前

    checkPauseAndStop() ,其目的是成为一个好的班轮,我可以定期呼吁内 run()

    在完全正常的情况下,停止线程是通过 InterruptedException
    (例如。线程。睡眠()不会再告诉您它可能引发这样的异常)。

    代码示例:

    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;
            }
        }
    

    // Do_stuff
    checkPauseRequest();
    

    而不是一个。

    3 回复  |  直到 6 年前
        1
  •  1
  •   Daniel Pryden    6 年前

    我会用一个 ScheduledExecutorService (您可以使用 Executors.newSingleThreadScheduledExecutor enum RunningState { RUNNING, PAUSED, STOPPED } .

    当国家 RUNNING ,我们继续调度延迟的任务(使用 ScheduledExecutorService.schedule ). 每项任务都会检查我们是否还活着 ,如果是,则将单个循环迭代排队(使用 ExecutorService.submit Executor.execute ). 然后它为下一次迭代安排一个新的延迟任务(与 Timer ,您可能会使用它来代替,但代价是另一个线程)。

    如果州政府 PAUSED ,我们不断地安排延迟的任务,以不断地检查转换回 跑步 州。但是我们不会为实际的循环迭代安排工作项。

    如果州政府 STOPPED 然后我们停止安排任何延迟的任务。

    状态变量可以存储在一个简单的 volatile

        2
  •  1
  •   nsuneja    6 年前

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

        3
  •  0
  •   Piohen    6 年前

    请确保你想要达到的目标是有意义的,而不是陷入困境 让我们重新发明轮子 https://docs.oracle.com/javase/10/docs/api/java/lang/Thread.html#stop() )(和线程。销毁()实际上没有实现。)

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