Java ScheduledThreadPoolBasedExecutor的执行顺序不正确
我使用ScheduledThreadPoolBasedExecutor来调度和执行callable。 根据:它以给定的延迟或(如果延迟相等)以FIFO顺序执行任务。为此,它甚至在实现中包含AtomicLong sequencer 我写了一个测试,它提交了很多计算素数的任务Java ScheduledThreadPoolBasedExecutor的执行顺序不正确,java,multithreading,Java,Multithreading,我使用ScheduledThreadPoolBasedExecutor来调度和执行callable。 根据:它以给定的延迟或(如果延迟相等)以FIFO顺序执行任务。为此,它甚至在实现中包含AtomicLong sequencer 我写了一个测试,它提交了很多计算素数的任务 public class MyCallable implements Callable<Boolean> { private static AtomicInteger counter = new Atomi
public class MyCallable implements Callable<Boolean> {
private static AtomicInteger counter = new AtomicInteger(0);
private final long prNumber;
private long callNanoTime;
private LocalDateTime callLocalDateTime;
private boolean isCalled = false;
public MyCallable(long number) {
this.prNumber = number;
}
public Boolean call() {
callNanoTime = System.nanoTime();
callLocalDateTime = LocalDateTime.now();
isCalled = true;
return isPrime(this.prNumber);
}
public boolean isCalled() {..}
public long getCallNanoTime() {..}
public LocalDateTime getCallLocalDateTime() {..}
private boolean isPrime(long n) {..}
}
事实上,可调用的调度到更晚的时间是在之前执行的。如果我增加粒度(任务之间的间隔为5-10毫秒),一切都很好
初始化和调度:
public class ScheduledThreadPoolBasedExecutor implements Executor {
private ScheduledExecutorService scheduledExecutorService;
private AtomicLong counter = new AtomicLong(0);
public ScheduledThreadPoolBasedExecutor() {
scheduledExecutorService = Executors.newScheduledThreadPool(1);
}
@Override
public void schedule(Callable callable, LocalDateTime localDateTime) {
long value = counter.incrementAndGet();
if (value % 100 == 0) {
System.out.println(String.format("Schedule callable #%s", value));
}
long delay = ChronoUnit.MILLIS.between(LocalDateTime.now(), localDateTime);
scheduledExecutorService.schedule(callable, delay, TimeUnit.MILLISECONDS);
}
}
这种1-3ms的不一致性是由操作系统和ScheduledThreadPoolBasedExecutor不保证此类时间的顺序造成的吗?还是我用错了?小更新:我发现,按照所需执行时间的增加顺序安排任务,一切都可以正常工作。Collections.shuffle导致测试失败。
public class ScheduledThreadPoolBasedExecutor implements Executor {
private ScheduledExecutorService scheduledExecutorService;
private AtomicLong counter = new AtomicLong(0);
public ScheduledThreadPoolBasedExecutor() {
scheduledExecutorService = Executors.newScheduledThreadPool(1);
}
@Override
public void schedule(Callable callable, LocalDateTime localDateTime) {
long value = counter.incrementAndGet();
if (value % 100 == 0) {
System.out.println(String.format("Schedule callable #%s", value));
}
long delay = ChronoUnit.MILLIS.between(LocalDateTime.now(), localDateTime);
scheduledExecutorService.schedule(callable, delay, TimeUnit.MILLISECONDS);
}
}