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

J2ME 多執行緒技術總結:三種實作模式與行動裝置實務應用

     編輯:Java 相關知識

J2ME 多執行緒必要性

行動裝置資源受限(CPU、記憶體、網路頻寬),單一執行緒會導致 UI 凍結、網路阻塞、遊戲幀率下降。KVM (K Virtual Machine) 提供精簡但完整的 java.lang.Thread 與 java.util.Timer API,支援執行緒建立、優先級、睡眠、等待/通知等核心功能。

模式一:繼承 Thread 類別

public class GameLoopThread extends Thread {
    private volatile boolean running = true;

    public void stopLoop() { running = false; }

    @Override
    public void run() {
        while (running) {
            // 遊戲邏輯更新
            updateGameState();
            // 重繪畫面
            repaintCanvas();
            // 幀率控制
            try { Thread.sleep(40); } // ~25 FPS
            catch (InterruptedException e) { break; }
        }
    }

    private void updateGameState() { /* ... */ }
    private void repaintCanvas() { /* 呼叫 Canvas.repaint() */ }
}

// 使用方式
GameLoopThread gameThread = new GameLoopThread();
gameThread.start(); // 自動呼叫 run()
// 遊戲結束時
gameThread.stopLoop();

特點

  • 直觀、封裝性好,執行緒邏輯內聚在子類別。
  • 無法繼承其他類別(Java 單一繼承限制)。

模式二:實作 Runnable 介面(推薦)

public class NetworkTask implements Runnable {
    private final String url;

    public NetworkTask(String url) { this.url = url; }

    @Override
    public void run() {
        HttpConnection conn = null;
        try {
            conn = (HttpConnection) Connector.open(url);
            int rc = conn.getResponseCode();
            if (rc == HttpConnection.HTTP_OK) {
                InputStream is = conn.openInputStream();
                // 解析回應...
                parseResponse(is);
            }
        } catch (IOException e) {
            handleError(e);
        } finally {
            closeQuietly(conn);
        }
    }
    // 輔助方法略...
}

// 使用方式
Thread networkThread = new Thread(new NetworkTask("https://api.example.com/data"));
networkThread.start();

優點

  • 職責分離:任務邏輯與執行緒控制解耦。
  • 可同時實作其他介面、繼承其他類別。
  • 任務物件可重複提交給不同執行緒或執行緒池(雖 J2ME 無標準池)。

模式三:Timer + TimerTask 定時排程

public class StatusReporter extends TimerTask {
    private final DeviceClient client;

    public StatusReporter(DeviceClient client) { this.client = client; }

    @Override
    public void run() {
        // 定期上報裝置狀態
        client.sendHeartbeat();
    }
}

// 排程使用
Timer timer = new Timer();
// 3 秒後首次執行,之後每 30 秒執行一次
timer.schedule(new StatusReporter(client), 3000, 30000);

// 取消排程
timer.cancel(); // 也會取消所有已排程任務

適用場景

  • 週期性任務:心跳、同步時間、檢查更新、動畫幀推進。
  • 延遲單次執行:timer.schedule(task, delay)。

注意事項

  • Timer 內部只有一個背景執行緒,**任務執行時間過長會阻塞後續任務**;耗時操作請在任務中另開執行緒。
  • J2ME Timer 不支援固定頻率(fixed-rate)模式,只有固定延遲(fixed-delay)。

核心 Thread API 快速查閱

方法說明
start()將執行緒置為可執行狀態,由排程器決定何時執行 run(),**非立即執行**
run()執行緒主體邏輯,**直接呼叫不會開新執行緒**
sleep(ms)靜態方法,讓**目前執行緒**睡眠指定毫秒,不釋放鎖
yield()靜態方法,暗示排程器讓出 CPU 給同優先級執行緒
join()等待該執行緒終止
setPriority(int)設定優先級(MIN=1, NORM=5, MAX=10),KVM 排程器參考但不保證
isAlive()判斷執行緒是否仍在執行(已啟動且未終止)
interrupt()中斷阻塞中的執行緒(sleep、wait、join 會拋出 InterruptedException)

行動裝置實務應用範例:按鍵響應中開啟網路執行緒

public class GameCanvas extends Canvas implements CommandListener {
    private Command cmdSync = new Command("同步", Command.OK, 1);
    private Command cmdExit = new Command("離開", Command.EXIT, 2);

    public GameCanvas() {
        addCommand(cmdSync);
        addCommand(cmdExit);
        setCommandListener(this);
    }

    public void commandAction(Command c, Displayable d) {
        if (c == cmdSync) {
            // ★ 關鍵:網路操作必須在新執行緒,避免阻塞 UI 執行緒導致裝置當機
            new Thread(new Runnable() {
                public void run() {
                    syncWithServer(); // 耗時 HTTP 請求
                }
            }).start();
        } else if (c == cmdExit) {
            notifyDestroyed();
        }
    }

    private void syncWithServer() {
        // 實作網路同步邏輯...
        // 完成後可用 Display.callSerially() 回到 UI 執行緒更新畫面
    }
}

J2ME 多執行緒最佳實踐清單

  1. UI 操作只能在事件執行緒:使用 Display.callSerially(Runnable) 將畫面更新排程回 UI 執行緒。
  2. 網路/IO/資料庫必須離開 UI 執行緒:否則裝置會出現「沙漏」或直接當機。
  3. 善用 volatile 控制迴圈旗標:volatile boolean running 確保跨執行緒可見性。
  4. 捕獲 InterruptedException 正確結束執行緒:不要吞掉中斷,重設中斷旗標或 break 迴圈。
  5. 避免在 run() 直接操作 RecordStore:若頻繁存取,考慮單一寫入執行緒 + 佇列。
  6. 記憶體敏感:執行緒棧大小有限(部分裝置 4-8KB),避免深層遞迴、大區域陣列。

總結:J2ME 雖輕量,但 Thread、Runnable、TimerTask 三大模式已足夠應對行動裝置的並發需求。核心原則:**UI 執行緒只做 UI,耗時工作全丟給背景執行緒**,並妥善處理生命週期與資源釋放。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved