J2ME 提供 HttpConnection(應用層 HTTP 協議支持)與 SocketConnection(傳輸層原始 Socket 流)兩種網絡 API。對上層業務邏輯而言,協議選擇應透明化;框架層需提供統一介面、連接復用、超時控制與異步非阻塞能力。
| 維度 | HttpConnection | SocketConnection |
|---|---|---|
| 協議層級 | 應用層 (HTTP/1.1) | 傳輸層 (TCP/UDP) |
| 連接管理 | 請求級連接,難以長連接 | 支持長連接與連接池 |
| 雙工通訊 | 半雙工(請求-響應) | 全雙工,可同時收發 |
| 防火牆穿透 | 優(標準 80/443 端口) | 差(需特定端口開放) |
| 適用場景 | REST API、文件下載、Web 服務 | 即時通訊、遊戲同步、自定義協議 |
實現全雙工需應用層協議配合:
public void sendRequestAsync(final NetworkRequest req, final long timeout) {
new Thread(() -> {
synchronized (req) { // 關鍵:同步塊必須包含發送與等待
Thread sender = new Thread(() -> {
try { sendRequest(req); }
catch (Exception e) { req.setError(e); }
finally { synchronized(req) { req.notifyAll(); } }
});
sender.start();
try { req.wait(timeout); }
catch (InterruptedException ignored) {}
if (req.isDelayed()) { // 超時處理
requestQueue.remove(req);
timeoutQueue.add(req);
}
}
}).start();
}
初版代碼將 synchronized(req) 放在子線程啟動之後,導致竝態條件:發送線程可能在主線程進入 wait() 前已調用 notifyAll(),造成主線程永久等待超時。修正為同步塊包裹線程啟動與等待,確保內存可見性與原子性。
採用雙隊列機制:
延遲響應到達時,活躍隊列無對象則丟棄;超時隊列中對象可觸發降級邏輯(如緩存更新)。
ERR_TIMEOUT, ERR_CONN_REFUSED, ERR_PROTOCOL, ERR_IO成熟的網絡層框架能屏蔽底層協議差異,讓業務代碼專注於領域邏輯,是 J2ME 應用穩定性的基石。