Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当池大小为1时,ScheduledExecutorService是否保证订单?_Java_Concurrency_Java.util.concurrent - Fatal编程技术网

Java 当池大小为1时,ScheduledExecutorService是否保证订单?

Java 当池大小为1时,ScheduledExecutorService是否保证订单?,java,concurrency,java.util.concurrent,Java,Concurrency,Java.util.concurrent,我有一个ScheduledExecutorService,其池大小为1线程 如果我使用该服务以相同的延迟调度多个任务,那么在执行过程中是否保留了调度顺序?是,保留了调度顺序。来自javadocs 延迟任务在启用之前执行,但在启用后何时开始没有任何实时保证。按提交的先进先出(FIFO)顺序启用为完全相同的执行时间安排的任务 你也可以在行动中看到这一点 public static void main(String args[]) { ScheduledExecutorServ

我有一个
ScheduledExecutorService
,其池大小为
1
线程


如果我使用该服务以相同的延迟调度多个任务,那么在执行过程中是否保留了调度顺序?

是,保留了调度顺序。来自javadocs

延迟任务在启用之前执行,但在启用后何时开始没有任何实时保证。按提交的先进先出(FIFO)顺序启用为完全相同的执行时间安排的任务

你也可以在行动中看到这一点

    public static void main(String args[]) {
        ScheduledExecutorService e = Executors.newScheduledThreadPool(1);
        
        e.schedule(delay("delay for 1 second", 10), 1, TimeUnit.SECONDS);
        e.schedule(delay("delay for 5 second", 0), 5, TimeUnit.SECONDS);
        e.schedule(delay("delay for 3 second", 0), 3, TimeUnit.SECONDS);
        e.schedule(delay("delay for 7 second", 0), 7, TimeUnit.SECONDS);
        e.schedule(delay("delay for 2 second", 0), 2, TimeUnit.SECONDS);
    }
    
    private static Runnable delay(String message, int initialDelay) {
        return () -> {
            Thread.sleep(initialDelay);
            System.out.println(message);
        };
    }
印刷品

delay for 1 second
delay for 2 second
delay for 3 second
delay for 5 second
delay for 7 second

是的,只要所使用的调度程序实现符合接口规范。例如,
newscheduledthreadpoolexecutor(1)
将使用一个
DelayedWorkQueue
,它将保留顺序

根据所有
ScheduledExecutorService
实施应保持顺序:

按提交的先进先出(FIFO)顺序启用为完全相同的执行时间安排的任务

可以使用以下示例测试实现:

import com.google.code.tempusfugit.concurrency.IntermittentTestRunner;
import com.google.code.tempusfugit.concurrency.annotations.Intermittent;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

import static org.assertj.core.api.Assertions.assertThat;


@RunWith(IntermittentTestRunner.class)
public class ScheduledExecutorServiceTest {
    @Test
    @Intermittent(repetition = 20)
    public void preservesOrderOfTasksScheduledWithSameDelay() throws InterruptedException {
        ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1);

        AtomicInteger atomicInteger = new AtomicInteger(0);
        int numTasks = 1_000;
        CountDownLatch countDownLatch = new CountDownLatch(numTasks);
        for (int i = 0; i < numTasks; i++) {
            int finalI = i;
            scheduledExecutorService.schedule(() -> {
                atomicInteger.compareAndSet(finalI, finalI + 1);
                countDownLatch.countDown();
            }, 10, TimeUnit.MILLISECONDS);
        }
        countDownLatch.await();

        assertThat(atomicInteger.get()).isEqualTo(numTasks);
    }
}
import com.google.code.tempusfugit.concurrency.间歇性TestRunner;
导入com.google.code.tempusfugit.concurrency.annotations.interactive;
导入org.junit.Test;
导入org.junit.runner.RunWith;
导入java.util.concurrent.*;
导入java.util.concurrent.AtomicInteger;
导入静态org.assertj.core.api.Assertions.assertThat;
@RunWith(间歇性TestRunner.class)
公共类ScheduledExecutorServiceTest{
@试验
@间歇性(重复次数=20次)
public void preservesOrderOfTasksScheduledWithSameDelay()引发InterruptedException{
ScheduledExecutorService ScheduledExecutorService=新ScheduledThreadPoolExecutor(1);
AtomicInteger AtomicInteger=新的AtomicInteger(0);
int numTasks=1_000;
CountDownLatch CountDownLatch=新的CountDownLatch(numTasks);
对于(int i=0;i{
原子整数。比较数据集(finalI,finalI+1);
countdownlock.countDown();
},10,时间单位为毫秒);
}
倒计时闩锁。等待();
assertThat(atomicInteger.get()).isEqualTo(numTasks);
}
}