首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME Timer 類別:簡化多任務排程的利器

     編輯:J2ME

背景

J2SE 1.3 引入 java.util.Timer/TimerTask,MIDP 同步納入,讓 J2ME 開發者擁有背景執行緒排程能力,無需手寫執行緒管理。

核心類別

類別角色
TimerTask抽象基類,實作 Runnable,開發者繼承並實作 run()
Timer排程器,內部維護單一背景執行緒,負責建立/管理任務執行

基本用法

1. 定義任務

import java.util.*;

public class MyTask extends TimerTask {
    public void run() {
        System.out.println("Running the task");
    }
}
注意:每個 Timer 同一時間只能執行一個任務,run() 必須**快速結束**,避免阻塞後續任務。

2. 排程執行

Timer timer = new Timer();
TimerTask task = new MyTask();

// 10 秒後執行一次
timer.schedule(task, 10000);

// 5 秒後首次執行,之後每 10 秒重複
timer.schedule(task, 5000, 10000);

// 指定時間點執行
timer.schedule(task, new Date(System.currentTimeMillis() + 10000));

// 固定頻率 (以首次執行時間為基準校正漂移)
timer.scheduleAtFixedRate(task, 5000, 10000);

3. 取消與清理

  • task.cancel():取消單一任務 (可在任務內部呼叫自殺)
  • timer.cancel():終止 Timer 背景執行緒,**不可恢復**,需重新 new Timer()

Thread-Safe 特性

Timer 內部同步處理,多執行緒環境可直接呼叫其方法,無需額外同步。

完整 MIDlet 範例:星空滾動特效

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.*;

public class TimerDemo extends MIDlet {
    private Display display;
    private StarField field = new StarField();
    private FieldMover mover = new FieldMover();
    private Timer timer = new Timer();

    public TimerDemo() {
        display = Display.getDisplay(this);
    }

    protected void destroyApp(boolean unconditional) {}
    protected void pauseApp() {}

    protected void startApp() {
        display.setCurrent(field);
        timer.schedule(mover, 100, 100); // 100ms 間隔重複執行
    }

    public void exit() {
        timer.cancel(); // 停止滾動
        destroyApp(true);
        notifyDestroyed();
    }

    class FieldMover extends TimerTask {
        public void run() {
            field.scroll();
        }
    }

    class StarField extends Canvas {
        private int height, width;
        private int[] stars;
        private Random random = new Random();
        private boolean painting = false;

        public StarField() {
            height = getHeight();
            width = getWidth();
            stars = new int[height];
            for (int i = 0; i < height; i++) stars[i] = -1;
        }

        public void scroll() {
            if (painting) return;
            for (int i = height - 1; i > 0; i--) {
                stars[i] = stars[i - 1];
            }
            stars[0] = (random.nextInt() % (3 * width)) / 2;
            if (stars[0] >= width) stars[0] = -1;
            repaint();
        }

        protected void paint(Graphics g) {
            painting = true;
            g.setColor(0, 0, 0);
            g.fillRect(0, 0, width, height);
            g.setColor(255, 255, 255);
            for (int y = 0; y < height; y++) {
                int x = stars[y];
                if (x == -1) continue;
                g.drawLine(x, y, x, y); // 畫點
            }
            painting = false;
        }

        protected void keyPressed(int keyCode) {
            exit(); // 任意鍵退出
        }
    }
}

關鍵設計亮點

  1. 單一 Timer 足夠:一個 MIDlet 通常只需一個 Timer,所有週期性任務共用
  2. scroll() 非阻塞:快速更新資料結構並呼叫 repaint(),實際繪製交給事件執行緒
  3. painting 旗標防重入:避免 scroll() 與 paint() 並發存取 stars 陣列
  4. 退出清理:exit() 中呼叫 timer.cancel() 確保背景執行緒正常終止

適用場景

  • 遊戲主迴圈替代方案 (固定幀率更新)
  • 動畫/特效定時觸發
  • 網路輪詢/心跳封包
  • 資料定期存檔/同步
  • 任何需「延遲執行」或「週期性執行」的邏輯
Timer 將「時間」維度從業務邏輯中剝離,讓開發者以宣告式方式描述排程需求,是 J2ME 開發中被低估卻極實用的工具類。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved