J2ME (KVM) 完整支援 Java 多線程 API。本文系統整理三種建立線程方式、核心方法、線程安全要點,並給出「按鍵響應中耗時操作必須放入獨立線程」的實戰模式代碼。
三種建立線程方式
1. 繼承 Thread 類
public class MyThread extends Thread {
public void run() {
// 線程主體
}
}
// 啟動
new MyThread().start();
2. 實現 Runnable 介面(推薦,解耦)
public class MyTask implements Runnable {
public void run() {
// 線程主體
}
}
// 啟動
new Thread(new MyTask()).start();
3. Timer + TimerTask 定時/週期任務
public class MyTimerTask extends TimerTask {
public void run() {
// 任務主體
}
}
// 3秒後執行一次
new Timer().schedule(new MyTimerTask(), 3000);
// 3秒後首次,之後每5秒執行一次
new Timer().schedule(new MyTimerTask(), 3000, 5000);
// 取消
timer.cancel();
Thread 核心方法速查
| 方法 | 說明 |
setPriority(int) | 設定優先級(MIN/MAX/NORM_PRIORITY) |
sleep(long ms) | 靜態方法,當前線程休眠 |
start() | 進入就緒狀態,等待調度 |
run() | 線程主體(不可直接調用) |
join() | 等待該線程終止 |
isAlive() | 是否存活 |
yield() | 讓出 CPU,嘗試讓同優先級線程執行 |
實戰模式:按鍵事件中啟動耗時操作
public void commandAction(Command c, Displayable d) {
if (c == cmdNetwork) {
// 模式 A: 匿名 Runnable
new Thread(new Runnable() {
public void run() { doNetworkOp(); }
}).start();
} else if (c == cmdGameLogic) {
// 模式 B: 繼承 Thread
new GameLogicThread().start();
} else if (c == cmdPeriodic) {
// 模式 C: Timer 週期任務
new Timer().schedule(new PeriodicTask(), 0, 10000);
}
}
關鍵最佳實踐
- 事件分發線程 (EDT) 絕不可阻塞:網路、RMS、大量計算、媒體載入全須放入背景線程,否則 UI 凍結、按鍵無響應、甚至看門狗重啟。
- UI 更新必須回 EDT:背景線程算完後,用
Display.callSerially(Runnable) 或同步鎖安全更新 UI 組件。
- 共享數據同步:用
synchronized 保護共享變量,或採用不可變物件傳遞。
- 線程數量克制:手機 CPU/記憶體有限,避免無限創建線程,採用線程池或 Timer 復用。
- 異常處理:
run() 內須全包 try-catch,未捕獲異常會導致線程靜默死亡且無日誌。
- 資源清理:線程結束時關閉流、釋放鎖、取消 Timer。
常見誤區
- 直接呼叫
run() → 同步執行,不開新線程。
- 在
run() 中無限循環無 sleep/yield → 佔滿 CPU,系統卡死。
- 背景線程直接操作
Form/Canvas → 競態條件、繪製異常。
- 以為
TimerTask 在獨立線程 → 實際共用 Timer 內部單線程,耗時任務會阻塞後續任務。
總結
掌握 Thread/Runnable/Timer 三種模式,牢記「EDT 不阻塞、UI 回 EDT、共享加鎖、線程可控」,即能在 J2ME 中寫出穩健的並發程序。
- 上一篇文章: J2ME 遊戲 API 地圖構建利器:TiledLayer 完整解析與貼磚實戰
- 下一篇文章: Java ME 藍牙開發實戰:設備發現、服務查詢與 OBEX 文件傳輸完整流程
Copyright ©
程式碼之家 All Rights Reserved