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

Java 使用ScheduledExecutorService,如何在不等待其他线程以固定间隔完成的情况下启动一个线程?,java,multithreading,Java,Multithreading,我希望在每个特定的时间间隔运行一个任务,而不管前一个线程是否完成。我使用了ScheduledExecutorService,每一秒都有一个时间表时间。但问题是,在我的Runnable中,如果我让线程休眠5秒,ScheduledExecuterService也会每5秒执行一次,而它应该每1秒运行一个线程 似乎它ScheduledExecuterService正在等待上一个线程完成。但我希望,无论任务中的作业等待更长的时间,任务都会每1秒触发一次 这是我的密码 public class MyTask

我希望在每个特定的时间间隔运行一个任务,而不管前一个线程是否完成。我使用了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);
   }
}
如果我做错了,请纠正我。如果我错了,有没有其他方法可以达到同样的效果?提供任何最佳实践都会更有帮助:

您看到的行为与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);
    }

}

请注意,在ScheduledExecutorService实例上使用schedule而不是scheduleAtFixedRate。它还会在启动新任务时安排下一个任务。

如果此任务的任何执行时间超过其周期,则后续执行可能会延迟启动,但不会同时执行。您看到的行为与文档一致。它正在工作。但当我们在main中执行此操作时,为什么要在MyTask的run方法中进行调度呢?调度只安排1次执行。在上面的示例代码中,在main方法中,它将1执行时间安排为1000毫秒。为了得到重复执行,run方法必须使用schedule安排再执行一次。这个循环会不断重复,总是在未来再安排1次1000毫秒的执行。