單線程(schedule)與多線程(ScheduledExecutorService)實現定時器任務管理及查詢__並發

來源:互聯網
上載者:User
0、序

    在遊戲工程地開發過程中,定時器功能是一般遊戲必不可少的功能,同時,在其他類型的項目中,也會時常需要用到定時器的方法。例如遊戲中建造一個建築需要倒計時等。下面從單線程和多線程兩個方面實現定時器的功能。
1、單線程(schedule)

    首先我們需要一個單獨的定時任務類,繼承TimerTask,用來表示具體的定時任務,單獨提出來封裝成一個類,方便管理和實現:

import java.util.TimerTask;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.Future;public class SystemTimerTask  extends TimerTask{private long taskID;//任務IDprivate long runtime;//倒計時的具體時間(以秒為單位)private ConcurrentHashMap<Long, Future<Long>> futureMap; public SystemTimerTask(Long taskID,long runtime) {this.taskID = taskID;this.runtime = runtime;}    @Override    public void run() {    System.out.println("Time Remain: "+this.runtime);    if (this.runtime-- <= 0 ) {              try {                  Future<Long> future = futureMap.remove(taskID);                  future.cancel(true);              } finally {                  System.out.println("###### Task "+taskID +" is Completed!!");              }          }     }public long getRemaintime() { return runtime; }public long getTaskID() { return taskID; }}

    在單線程的情況下,不需要考慮其他條件直接調用 schedule 方法即可實現,具體調用方法如下:

Timer timer = new Timer(); SystemTimerTask() task =  new SystemTimerTask(10001,20);timer.schedule(task ,0,1000); 

    關於schedule 方法聲明為:schedule(TimerTask task, long delay, long period)

    --task:被調度的定時任務;

    --delay:以毫秒為單位,表示任務延遲delay毫秒後執行;

    --period:以毫秒為單位,表示任務執行期間,也就是定時器初始值。
2、多線程(ScheduledExecutorService)     在實際應用開發中,單線程應用的範圍很窄,並發是項目開發中必不可少的需要考慮到的因素,在定時器實現中,採用多線程,可以更有效率地實現多個定時器並行作業,同時,可以在一個大的項目中,對定時任務線程實施更方便地管理和查看。所以,我們在Java內建定時任務線程池ScheduledExecutorService基礎上,封裝成一個定時任務線程管理類,如下:

import java.util.Iterator;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;//根據具體包名,將SystemTimerTask包含進來public class TimerManager {    private static TimerManager instance;    private TimerManager() {    }    public static TimerManager getInstance() {        if(instance == null) {            return new TimerManager();        }        return instance;    }private ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();  //初始化ScheduledExecutorService線程池,具體長度視情況而定private static ConcurrentHashMap<Long, SystemTimerTask> taskmap = new ConcurrentHashMap<Long, SystemTimerTask>();//採用以任務ID為key的雜湊表儲存所有實現的定時任務public boolean StartTimer(long id,long time,long initialDelay, long period, TimeUnit unit ) {if(taskmap.containsKey(id) ){return false;}else{SystemTimerTask task_time = new SystemTimerTask(id,time);this.addTask(id, task_time);Iterator keys = taskmap.keySet().iterator();          while(keys.hasNext()){              Long key = (Long)keys.next();              if(key == id)            System.out.println("是否存在------------- "+ (key == id)+"   id: "+id);         }        System.out.println("是否存在+++++++++++ "+ taskmap.get(id).getRemaintime()); this.service.scheduleAtFixedRate(task_time, initialDelay,period, unit);return true;}}    public ScheduledExecutorService getService() {return service;}public void setService(ScheduledExecutorService service) {this.service = service;}public long getRemain(long id) {if(this.getTask().containsKey(id)){return this.getTask().get(id).getRemaintime();}elsereturn -1;}public ConcurrentHashMap<Long, SystemTimerTask> getTask() {return taskmap;}public void addTask( long id ,SystemTimerTask task1) {taskmap.put(id, task1) ;}}

    以上將定時器管理類設定為單例模式,防止其他對象對自己執行個體化,確保所有對象訪問的都是一個執行個體。

scheduleAtFixedRate 方法的參數說明同上面的 Timer類中的 schedule 方法。可自行查閱。

    以下為其測試主函數:

public static void main(String[] args) throws InterruptedException {long remain = 10;long remain2 = 20;System.out.println("Start:");long id1 = 100;long id2 = 110;TimerManager.getInstance().StartTimer(id1, remain, 0, 1, TimeUnit.SECONDS);TimerManager.getInstance().StartTimer(id2, remain2, 0, 1, TimeUnit.SECONDS);Thread.sleep(3000);System.out.println("是否存在::::"+ TimerManager.getInstance().getTask().containsKey(id1));System.out.println("+++++++++++++++++++++Time remain................ :"+TimerManager.getInstance().getRemain(id2));}
3、總結    在本文中,基於單線程和多線程兩種方式實現定時器的功能,兩種各有優缺點,合理採納。同時,在多線程實現中,有一點不足之處,在具體應用的時候希望改正,就是定時任務ID可以採用自動產生的增長序列,保證其唯一性,因為時間關係,本文尚未添加。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.