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

Java 5 併發編程實戰:線程池、阻塞隊列、鎖與 Future 綜合應用

     編輯:Java 相關知識

Java 5 引入 java.util.concurrent 包,徹底改變了多線程開發面貌。本文通過構建網絡服務器模型,實戰演練線程池、阻塞隊列、可重入鎖、Callable/Future、泛型等核心特性。

模型演進:從「線程巧克力」到線程池

傳統模型缺陷

  1. 建立監聽端口
  2. 接收連接 → new Thread() 處理
  3. 服務結束 → 線程銷毀

痛點:短連接高併發下,線程創建/銷毀開銷巨大,甚至導致 OOM。

線程池優化模型

  1. 建立監聽端口 + 創建線程池
  2. 接收連接 → 提交任務到線程池
  3. 任務完成 → 線程歸還池中

核心 API 實戰

1. 線程池初始化

ExecutorService pool = Executors.newFixedThreadPool(10); // 固定 10 線程
ServerSocket serverSocket = new ServerSocket(19527);
serverSocket.setReuseAddress(true);

2. 任務提交循環

while (true) {
    Socket socket = serverSocket.accept(); // 阻塞等待連接
    pool.execute(new ServiceThread(socket)); // 提交 Runnable 任務
}

3. 服務任務:可重入鎖保護共享計數器

class ServiceThread implements Runnable {
    private static final ReentrantLock lock = new ReentrantLock();
    private static int count = 0;
    private final Socket socket;

    public ServiceThread(Socket socket) { this.socket = socket; }

    private int getCount() {
        lock.lock();
        try { return count; }
        finally { lock.unlock(); }
    }

    private void increaseCount() {
        lock.lock();
        try { count++; }
        finally { lock.unlock(); }
    }

    public void run() {
        try {
            increaseCount();
            int id = getCount();
            
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
            dos.write(("hello, id = " + id + "\r\n").getBytes());

            // 費時任務異步執行:Callable + Future
            ExecutorService executor = Executors.newSingleThreadExecutor();
            Future future = executor.submit(new TimeConsumingTask());
            
            dos.write("let's do something other\r\n".getBytes());
            
            String result = future.get(); // 阻塞獲取結果,若已完成則立即返回
            dos.write((result + "\r\n").getBytes());
            
        } catch (Exception e) { e.printStackTrace(); }
    }
}

4. Callable 任務與泛型

class TimeConsumingTask implements Callable { // 泛型指定返回類型
    public String call() throws Exception {
        System.out.println("Time-consuming task running...");
        Thread.sleep(3000); // 模擬耗時操作
        return "ok, result produced after long time";
    }
}

關鍵技術點解析

特性傳統寫法Java 5 寫法優勢
線程管理new Thread()ExecutorService + 線程池復用線程、控制併發數、拒絕策略
同步鎖synchronizedReentrantLock可中斷、超時獲取、公平鎖、條件變量
異步結果共享變量 + wait/notifyCallable + Future類型安全、異常傳播、可取消、超時獲取
類型安全Object 強轉泛型編譯期檢查、消除強轉

Future.get() 語義深度理解

Future future = executor.submit(task);
// 此處主線程可繼續做其他事...
dos.write("other work".getBytes()); // 並行執行!

String result = future.get(); // 此處阻塞直到任務完成
// 若任務已完成:立即返回結果
// 若任務未完成:等待完成
// 若任務拋異常:拋出 ExecutionException

這實現了「提交即忘、需要時取」的異步編程模式,充分利用多核 CPU。

生產環境擴展建議

  • 使用 ThreadPoolExecutor 精確控制核心/最大線程數、隊列類型、拒絕策略
  • 業務線程池與異步任務線程池隔離,避免相互影響
  • 引入 CompletionService 批量管理 Future 結果
  • 監控線程池指標:activeCount、queueSize、completedTaskCount
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved