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

Java 取得執行緒執行結果兩大模式:輪詢 vs 回呼機制比較

     編輯:Java 相關知識

問題背景

主執行緒啟動工作執行緒後,如何取得執行結果?直接呼叫 getter 會因競態條件拿到初始值。

模式一:輪詢

// 工作執行緒
class Worker extends Thread {
    private String result;
    public void run() {
        // 耗時運算
        result = "Hello World!";
    }
    public String getResult() { return result; }
}

// 主執行緒
Worker w = new Worker();
w.start();
while (true) {
    String r = w.getResult();
    if (!"Hello".equals(r)) { // 初始值不同
        System.out.println("結果: " + r);
        break;
    }
    Thread.sleep(100); // 降低 CPU 佔用
}

缺點:忙碌等待浪費 CPU、延遲不可控、難以設定逾時。

模式二:回呼

// 定義回呼介面
interface ResultCallback {
    void onResult(String result);
}

// 工作執行緒接受回呼
class Worker extends Thread {
    private final ResultCallback callback;
    Worker(ResultCallback cb) { callback = cb; }
    
    public void run() {
        String result = "Hello World!";
        callback.onResult(result); // 執行完成主動通知
    }
}

// 主執行緒實作回呼
public class Main {
    public static void main(String[] args) {
        new Worker(result -> {
            System.out.println("收到結果: " + result);
            // 後續處理...
        }).start();
        
        // 主執行緒可繼續做其他事
    }
}

進階:事件監聽器模式 (多觀察者)

class Worker extends Thread {
    private final List listeners = 
        Collections.synchronizedList(new ArrayList<>());
    
    public void addListener(ResultListener l) { listeners.add(l); }
    public void removeListener(ResultListener l) { listeners.remove(l); }
    
    public void run() {
        String result = compute();
        // 複製列表避免並發修改
        for (ResultListener l : new ArrayList<>(listeners)) {
            l.onResult(result);
        }
    }
}

interface ResultListener {
    void onResult(String result);
}

現代替代方案 (Java 8+)

最佳實務建議

  1. 優先使用 CompletableFuture 或 Future
  2. 回呼介面採用單一方法 (SAM) 便於 Lambda
  3. 避免在回呼中執行耗時/阻塞操作
  4. 異常必須在回呼鏈中傳遞處理
  5. 執行緒池隔離:CPU 密集 vs I/O 密集分離
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
API適用場景特點
Future.get()單一結果阻塞等待標準阻塞、可逾時、可取消
CompletableFuture非阻塞組合、多階段回呼鏈、異常處理、組合運算
CompletableFuture.supplyAsync簡單異步計算自動執行緒池、Lambda 友善
ExecutorService.submit(Callable)需回傳值的任務標準介面、支援檢查型異常