ScheduledExecutorService中scheduleAtFixedRate與scheduleWithFixedDelay的區別
阿新 • • 發佈:2018-11-12
昨天重構藍芽指令傳送模組,按照設想,當連續傳送指令時,每條指令至少間隔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(); @Overridepublic 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原始碼。