日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自己实现定时器

發布時間:2024/1/18 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自己实现定时器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

思路:

1.由于定時器涉及到時間問題。所以在線程執行時需要判斷時間是否允許,而且又是在多線程環境下,所以我們采用優先級阻塞隊列來存取任務。
2.存放的任務我們定義為 MyTimerTask 類,而且要重寫 Comparable 接口來確定優先級。
3.和實現前面的線程池方法類似,我們在創建定時器對象是直接確定線程池的大小和優先級阻塞隊列的大小,并且直接啟動線程。線程的 run 方法也是從優先級阻塞隊列中取任務并運行。
4.創建 schedule 方法,向優先級阻塞隊列中存入任務類。

參考代碼:

import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.PriorityBlockingQueue;public class MyTimerPool {// 優先級阻塞式隊列,存放的元素需要實現Comparable接口// MyTimerTask是根據next下次執行時間比較的,優先獲取next最小的private PriorityBlockingQueue<MyTimerTask> workQueue;// 執行的線程(類似固定線程池)private MyTimerThread[] threads;// 和線程池實現邏輯類似public MyTimerPool(int capacity, int size){this.threads = new MyTimerThread[capacity];workQueue = new PriorityBlockingQueue<>(size);for(int i=0; i<capacity; i++){threads[i] = new MyTimerThread(workQueue);threads[i].start();}}// 執行定時任務public void schedule(Runnable task, long delay, long period){workQueue.put(new MyTimerTask(task, delay, period));// 當前傳入的任務,下次執行時間可能是最小的,所以// 需要通知線程,重新從阻塞隊列中獲取元素synchronized (workQueue){workQueue.notifyAll();}}public static class MyTimerThread extends Thread{private PriorityBlockingQueue<MyTimerTask> workQueue;public MyTimerThread(PriorityBlockingQueue<MyTimerTask> workQueue) {this.workQueue = workQueue;}@Overridepublic void run() {try {while(true){// 阻塞式隊列take()方法是阻塞式的,poll()是非阻塞式MyTimerTask myTimerTask = workQueue.take();long current = System.currentTimeMillis();long next = myTimerTask.next;if(current < next){// 等待下次執行時間到了,或者被通知到synchronized (workQueue){workQueue.wait(next - current);// put()方法是阻塞式的,offer()是非阻塞的workQueue.put(myTimerTask);}} else {Date date = new Date(next);// 打印下次執行時間DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println("date="+df.format(date));myTimerTask.task.run();if(myTimerTask.period > 0){myTimerTask.next += myTimerTask.period;workQueue.put(myTimerTask);}}}} catch (InterruptedException e) {e.printStackTrace();}}}public static class MyTimerTask implements Comparable<MyTimerTask>{private long next;// 下次執行時間private Runnable task;private long period;public MyTimerTask(Runnable task, long delay, long period) {this.next = System.currentTimeMillis() + delay;this.task = task;this.period = period;}@Overridepublic int compareTo(MyTimerTask o) {return Long.compare(next, o.next);}}public static void main(String[] args) {MyTimerPool pool = new MyTimerPool(3, 1000);pool.schedule(new Runnable() {@Overridepublic void run() {System.out.println("明天要答辯");}}, 0, 1000);pool.schedule(new Runnable() {@Overridepublic void run() {System.out.println("后天要放假");}}, 1500, 3000);} }

總結

以上是生活随笔為你收集整理的自己实现定时器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。