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

從 Java 線程獲取運算結果的四種模式對比

     編輯:Java 相關知識

線程 run() 無返回值,如何將子線程計算結果傳回主線程?本文對比四種常見模式,由簡入深。

線程創建回顧

// 方式一:繼承 Thread
class AddThread extends Thread {
    public void run() { /* 計算 1+...+10000 */ }
}

// 方式二:實現 Runnable
class Add implements Runnable {
    public void run() { /* 同樣計算 */ }
}
// 啟動:new Thread(new Add()).start();

模式一:直接 get() —— 錯誤示範

class AddThread extends Thread {
    private int result = 0;
    public void run() { for(int i=1;i<=10000;i++) result+=i; }
    public int getResult() { return result; }
}
public class Test {
    public static void main(String[] args) {
        AddThread t = new AddThread();
        t.start();
        System.out.println("result: " + t.getResult()); // 輸出 0!
    }
}

原因:主線程與子線程並發,getResult() 在計算完成前調用。不可取。

模式二:輪詢標誌位 —— 可行但低效

class AddThread extends Thread {
    private int result = 0;
    private boolean done = false;
    public void run() { for(int i=1;i<=10000;i++) result+=i; done=true; }
    public boolean isDone() { return done; }
    public int getResult() { return result; }
}
public class Test {
    public static void main(String[] args) {
        AddThread t = new AddThread(); t.start();
        while (!t.isDone()) { try { Thread.sleep(100); } catch(Exception e){} }
        System.out.println("result: " + t.getResult()); // 正確
    }
}

缺點:主線程忙等消耗 CPU,sleep 間隔導致響應延遲。

模式三:wait/notify 協作 —— 推薦

class AddThread extends Thread {
    private final Object lock;
    private int result = 0;
    private boolean done = false;
    public AddThread(Object lock) { this.lock = lock; }
    public void run() {
        for(int i=1;i<=10000;i++) result+=i;
        synchronized(lock) { done=true; lock.notifyAll(); }
    }
    public boolean isDone() { return done; }
    public int getResult() { return result; }
}
public class Test {
    public static void main(String[] args) {
        Object lock = new Object();
        AddThread t = new AddThread(lock); t.start();
        synchronized(lock) {
            while (!t.isDone()) { try { lock.wait(); } catch(Exception e){} }
        }
        System.out.println("result: " + t.getResult());
    }
}

優點:主線程阻塞不佔用 CPU,響應即時。注意:wait/notify 必須在同步塊中,用 while 防虛假喚醒。

模式四:回調/觀察者模式 —— 最佳實踐

interface ResultProcessor { void process(int result); }

class AddThread extends Thread {
    private final ResultProcessor processor;
    public AddThread(ResultProcessor p) { this.processor = p; }
    public void run() {
        int result = 0; for(int i=1;i<=10000;i++) result+=i;
        processor.process(result); // 計算完成直接回調
    }
}
public class Test implements ResultProcessor {
    public void process(int result) { System.out.println("result: " + result); }
    public static void main(String[] args) {
        new AddThread(new Test()).start(); // 無需主線程等待
    }
}

優勢:解耦計算與處理、天然異步、支持多監聽者擴展、無同步煩惱。現代框架(如 CompletableFuture、ExecutorService)均採用類似回調/Future 模式。

總結建議

模式優點缺點適用場景
直接 get簡單結果錯誤不可用
輪詢易理解浪費 CPU、延遲教學演示
wait/notify阻塞高效、即時代碼較繁瑣底層協作、學習原理
回調解耦、異步、擴展性強需定義接口生產環境首選
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved