使用ScheduledExecutorService,如何在不等待其他线程以固定间隔完成的情况下启动线程?

时间:2017-12-06 02:04:43

标签: java multithreading

我想在每个特定的时间间隔运行一个任务,无论前一个线程是否完成。我已经将ScheduledExecutorService与每一秒的计划时间一起使用。但问题是,在我的Runnable中,如果我使线程休眠5秒,我的ScheduledExecuterService也会在每5秒执行一次,而它应该在1秒内运行每个线程。

似乎ScheduledExecuterService正在等待上一个线程完成。但我想,无论如何,如果任务内部的工作等待更长时间,则每1秒触发一次任务。

这是我的代码。

public class MyTask implements Runnable {

   public void run() {
       System.out.println("hi there at: "+ new java.util.Date());
       try {
           Thread.sleep(5000);
       } catch (InterruptedException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }
   }
}

这是我的ScheduledExecutorService代码。

public class JavaScheduledExecutorServiceExample {

   public static void main(String[] args) {
       ScheduledExecutorService execService = Executors.newScheduledThreadPool(5);
       execService.scheduleAtFixedRate(new MyTask(), 0, 1000, TimeUnit.MILLISECONDS);
   }
}

纠正我如果我做错了什么。如果我错了,有没有其他方法可以达到同样的目的?提供任何最佳实践可能会更有帮助:)

1 个答案:

答案 0 :(得分:1)

" If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute."您看到的行为与javadocs

一致

相信这将按您指定的方式执行:

public class JavaScheduledExecutorServiceExample {
    private static ScheduledExecutorService execService = null;
    private static int timesAsleep = 0;

    public static class MyTask implements Runnable {

        public void run() {
            System.out.println("hi there at: "+ new java.util.Date());
            // schedule again
            execService.schedule(new MyTask(), 1000, TimeUnit.MILLISECONDS);
            try {
                int i = timesAsleep;
                timesAsleep++;
                System.out.println("asleep " + i + "----------------------");
                Thread.sleep(5000);
                System.out.println("awoke " + i + "----------------------");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        execService = Executors.newScheduledThreadPool(5);
        execService.schedule(new MyTask(), 1000, TimeUnit.MILLISECONDS);
    }

}

请注意schedule()实例上使用scheduleAtFixedRate()而不是ScheduledExecutorService。它还会在启动 new 任务后立即安排 next 任务。