【问题标题】:Changing intervall of periodic action with Thread and Thread.sleep使用 Thread 和 Thread.sleep 改变周期性运动的间隔
【发布时间】:2015-11-12 14:43:41
【问题描述】:

我有一个周期性的动作,我想在定义的时间间隔内执行(以秒为单位的粒度)。所以我使用了一个线程,它在请求的时间内休眠,然后执行操作,然后再次休眠,依此类推..

  public class DiscoveryThread extends Thread
  {
    private int deviceDiscoveryIntervall = 1;

    public void setDeviceDiscoveryIntervall(int seconds)
    {
       deviceDiscoveryIntervall = seconds;
    }

    @Override
    public void run()
    {
      while(!isInterrupted())
      {
        //do there the action

        try 
        {
          sleep(deviceDiscoveryIntervall*1000);
        } 
        catch (InterruptedException e) 
        {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }

    }
  }

现在我有时想为周期性动作设置一个新的间隔。如果间隔在 10 秒之前,并且我在最后一个动作后 5 秒将其设置为 1 秒,那么无论如何我都必须等待 5 秒直到下一个动作,但在这种情况下它应该立即执行该动作。

那么我该怎么做呢?如果我使用interrupted() 方法,sleep 方法将抛出一个InterruptedException,我可以立即执行操作。但是我必须为整个循环使用自己的标志,因为我不想退出线程。在InterruptedException 之后再次调用sleep() 方法怎么样,中断标志是否仍然设置?我可以再次中断sleep() 方法吗?还有用interrupted()方法不停止线程怎么样,这不是误用吗?

【问题讨论】:

  • 与其盲目地休眠给定的秒数,不如在循环开始时检查实际时钟时间。如果是时候执行该操作,请执行它。否则,计算多久才能执行它,然后休眠该时间。如果睡眠由于中断而提前返回,没问题:它会再次睡眠。 (也就是说,假设中断并不意味着。)
  • 这也是一个解决方案,如果我总是睡一秒钟并在每个循环后检查我是否必须执行该操作或是否必须再睡一秒钟。

标签: java multithreading interrupted-exception


【解决方案1】:

线程应该等待具有正确超时的对象,当您希望线程提前唤醒时,请在对象上调用notifyAll

您应该考虑使用ScheduledExecutorService 来处理类似的事情,而不是尝试自己动手。

【讨论】:

    【解决方案2】:

    使用ScheduledExecutorService

    private final Runnable r = new Runnable() {
        @Override
        public void run() {
            // ...
        }
    };
    
    private final ScheduledExecutorService ses = 
        Executors.newSingleThreadScheduledExecutor();
    ScheduledFuture<?> sf = ses.scheduleAtFixedRate(r, 0, 10, TimeUnit.SECONDS);
    
    // change to 5 sec: cancel and reschedule
    sf.cancel();
    sf = ses.scheduleAtFixedRate(r, 0, 5, TimeUnit.SECONDS);
    

    【讨论】:

      猜你喜欢
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      • 2017-11-28
      • 2011-12-09
      • 2023-03-09
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多