ScheduledThreadPoolExecutor可以代替timer,timer的缺點是一個timer啟動一個線程,如果任務數量很多,會創建很多線程,不推薦使用。
ScheduledThreadPoolExecutor他有個線程池管理線程管理所有任務,效率更高
public class ScheduledThreadPoolExecutorTest { public static void main(String[] args) throws InterruptedException { // ScheduledThreadPoolExecutor schedulePool = new ScheduledThreadPoolExecutor(4); // 周期任務 // 從上一周期的任務的開始時間到當前周期的任務開始時間的間隔 // 任務的執行時間 > period參數:時間間隔是任務的執行時間。 // 任務的執行時間 < period參數:時間間隔是period參數。 ScheduledFuture<?> scheduledFuture = schedulePool.scheduleAtFixedRate(new MyRunnable(), 50, 5000, TimeUnit.MILLISECONDS); // 取消該任務 Thread.sleep(20000); scheduledFuture.cancel(true); // 延時任務 // 從上一周期的任務的執行結束時間到當前周期的任務開始時間的間隔,固定延遲時間為delay參數,與任務執行時間無關。 // schedulePool.scheduleWithFixedDelay(new MyRunnable(), 50, 1000, TimeUnit.MILLISECONDS); } static class MyRunnable implements Runnable { int period = 1; @Override public void run() { //為周期任務捕獲異常,避免異常影響下一周期的任務執行 try { System.out.println("---------------第 " + period + " 周期-------------"); System.out.println("begin = " + System.currentTimeMillis() / 1000);//秒 //任務執行時間 Thread.sleep(2000); System.out.println("end = " + System.currentTimeMillis() / 1000); period++; } catch (InterruptedException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } /** * 計算初始的延遲毫秒數 * @return */ public static long getDelayMillis(){ int dayOfHour = 0; // 24h 制 int minute = 0; int second = 0; long delay; //首次執行任務的延遲 Calendar c = Calendar.getInstance(); long currentTime = c.getTimeInMillis(); c.set(Calendar.HOUR_OF_DAY, dayOfHour); c.set(Calendar.MINUTE, minute); c.set(Calendar.SECOND, second); long executeTime = c.getTimeInMillis(); delay = executeTime - currentTime < 0 ? (executeTime + 24 * 60 * 60 * 1000 - currentTime ) : (executeTime - currentTime); System.out.println("DelayTimeInMillis =" + delay); return delay; } }
