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

Java 多線程與並發包入門:從基礎到生產者消費者模式實戰

     編輯:Java 程式設計入門

一、多線程基礎建立方式

方式 1:繼承 Thread 類

public static class Test1Thread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("Test1," + Thread.currentThread().getName() + ", i = " + i);
        }
    }
}
// 啟動:new Test1Thread().start();

方式 2:實作 Runnable 介面(推薦)

public static class Test2Thread implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("Test2," + Thread.currentThread().getName() + ", i = " + i);
        }
    }
}
// 啟動:new Thread(new Test2Thread()).start();

方式 3:匿名內部類

new Thread(new Runnable() {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("Test3," + Thread.currentThread().getName() + ", i = " + i);
        }
    }
}).start();

關鍵: 必須呼叫 start() 而非 run(),才會開啟新執行緒。

二、並發包核心:共享變數的線程安全方案

問題場景:多執行緒同時 count++

private static int count = 0; // 非線程安全

方案對比

方案核心類/關鍵字原理效能適用場景
無同步——最高單執行緒、只讀
互斥鎖synchronized監視器鎖,阻塞同步中臨界區邏輯複雜
CAS 原子類AtomicIntegerCompare-And-Swap,非阻塞高簡單計數、累加器
volatilevolatile可見性保證,非原子性最高狀態旗標、單次寫入

代碼實戰

// 1. 不安全
private static int count = 0;
// 2. synchronized
private static final Object lock = new Object();
synchronized(lock) { count++; }
// 3. AtomicInteger (CAS)
private static AtomicInteger ai = new AtomicInteger();
ai.incrementAndGet();
// 4. volatile (錯誤示範:++ 非原子)
private static volatile int countV = 0;
countV++; // 仍不安全!

三、生產者-消費者模式演進

核心角色

  • 生產者: 生成資料放入倉庫
  • 消費者: 從倉庫取出資料處理
  • 倉庫: 共享緩衝區,有容量上限

版本 1:無同步(錯誤)

public int put() { carList.add(car); carNums++; return carNums; }
public int get() { if (!carList.isEmpty()) { carList.remove(...); carNums--; } return carNums; }
// 問題:race condition、資料不一致

版本 2:synchronized 方法鎖

public synchronized int put() { ... }
public synchronized int get() { ... }
// 優點:簡單;缺點:粒度粗,吞吐受限

版本 3:wait/notify 精確控制(經典)


private Object lock = new Object();
public int put() {
    synchronized (lock) {
        while (carList.size() == MAX) lock.wait(); // 滿了等待
        carList.add(car); carNums++;
        lock.notify(); // 喚醒消費者
        return carNums;
    }
}
public int get() {
    synchronized (lock) {
        while (carList.isEmpty()) lock.wait(); // 空了等待
        carList.remove(...); carNums--;
        lock.notify(); // 喚醒生產者
        return carNums;
    }
}

關鍵點:

  • 用 while 而非 if 檢查條件(防止虛假喚醒)
  • notify() 喚醒單一執行緒,notifyAll() 喚醒全部
  • 鎖物件必須共享(此處為 lock)

線程狀態轉換

新建 → 就緒 → 執行 → 阻塞(wait/sleep/IO) → 死亡

四、生產建議

  1. 優先使用 BlockingQueue(ArrayBlockingQueue、LinkedBlockingQueue)替代手寫 wait/notify
  2. 大量併發計數用 LongAdder(Java 8+)優於 AtomicLong
  3. 避免過早優化,先正確再快
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved