昨天重构蓝牙指令发送模块,按照设想,当连续发送指令时,每条指令至少间隔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源码。