ScheduledExecutorService中scheduleAtFixedRate与scheduleWithFixedDelay的区别

 昨天重构蓝牙指令发送模块,按照设想,当连续发送指令时,每条指令至少间隔30ms,于是构造了一个指令队列,发送时把指令放入队列中,然后每隔30ms去队列中取出指令执行,如果队列为空,则挂起当前线程,很自然的想到BlockingQueue+ScheduledExecutorService,实现很简单,但在项目中并没有按照预期执行,于是写一个demo分析下,直接上代码。


public class CommandSchedule {

    private ScheduledExecutorService mCommandService;
    private LinkedBlockingQueue<String> mCommandQueue;

    public CommandSchedule() {
        mCommandService = Executors.newScheduledThreadPool(1);
        mCommandQueue = new LinkedBlockingQueue<>();
        mCommandService.scheduleAtFixedRate(new Runnable() {
            long lastTime = System.currentTimeMillis();

            @Override
            public void run() {
                try {
                    String commandBean = mCommandQueue.take();
                    if (commandBean != null) {
                        System.out.println("time = " + (System.currentTimeMillis() - lastTime));
                        lastTime = System.currentTimeMillis();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }, 0, 30, TimeUnit.MILLISECONDS);
    }

    public void postQueue(String str) {
        mCommandQueue.offer(str);
    }
}


测试代码


public static void main(String[] args) {
    CommandSchedule schedule = new CommandSchedule();
    for(int i=0;i<10;i++){
        schedule.postQueue("");
    }
}


执行结果




没什么问题,每30ms执行了一次,接下来我1000ms后再调用postQueue


public static void main(String[] args) {
    CommandSchedule schedule = new CommandSchedule();
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    for(int i=0;i<10;i++){
        schedule.postQueue("");
    }
}


执行结果



这显然不符合我的期望,将方法替换成scheduleWithFixedDelay,结果和第一次运行一样

很容易从结果看到它们之间的区别,就不多说了,有兴趣的自行看jdk源码。

猜你喜欢

转载自blog.csdn.net/msl0903/article/details/79252549