我使用ScheduledThreadPoolBasedExecutor来安排和执行callable。 根据{{3}}:它以FIFO顺序执行具有给定延迟的任务或(如果延迟相等)。为此,它甚至在实现中包含AtomicLong音序器。
我写了测试,提交了许多计算素数的任务。
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) {..}
}
我以这种方式提交任务: 1)获取间隔(从现在开始的2秒到现在的6秒) 2)生成4000个任务并按统一分布(实际每毫秒)安排它们
我按计划时间排序了callables,并检查callNanoTime是否为非增加(显然它必须为true)但实际上没有,我的测试输出结果如下:
Callable scheduled to: '2018-01-28T14:04:13.866' was called in: '61665400763727', but callable scheduled to: '2018-01-28T14:04:13.868' was called in: '61665397242047'
实际上,调度计划到以后的时间才执行。如果我增加粒度(让任务之间的间隔为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);
}
}
操作系统和ScheduledThreadPoolBasedExecutor引起的这种1-3ms不一致是否不能保证此类时间的顺序?或者我错误地使用它?