Java 多執行緒 (Multithreading)
多執行緒讓程式可以同時執行多個任務,提高效能和回應性。
建立執行緒
方式一:繼承 Thread
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("執行緒執行中:" + getName());
}
}
// 使用
MyThread thread = new MyThread();
thread.start(); // 啟動執行緒
方式二:實作 Runnable(推薦)
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("執行緒執行中");
}
}
// 使用
Thread thread = new Thread(new MyRunnable());
thread.start();
// Lambda 寫法
Thread thread2 = new Thread(() -> {
System.out.println("Lambda 執行緒");
});
thread2.start();
方式三:Callable(有回傳值)
import java.util.concurrent.*;
Callable<Integer> task = () -> {
return 42;
};
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(task);
Integer result = future.get(); // 取得結果(會等待)
System.out.println(result); // 42
executor.shutdown();
執行緒方法
Thread thread = new Thread(() -> {
System.out.println("執行中...");
});
thread.start(); // 啟動執行緒
thread.join(); // 等待執行緒結束
thread.join(1000); // 最多等待 1 秒
Thread.sleep(1000); // 休眠 1 秒
thread.interrupt(); // 中斷執行緒
thread.isAlive(); // 是否執行中
thread.getName(); // 取得名稱
thread.setName("MyThread"); // 設定名稱
thread.setPriority(5); // 設定優先權(1-10)
Thread.currentThread(); // 取得目前執行緒
更多說明請參考 Java 執行緒生命週期。
同步 (Synchronization)
synchronized 方法
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
synchronized 區塊
public class Counter {
private int count = 0;
private final Object lock = new Object();
public void increment() {
synchronized (lock) {
count++;
}
}
}
更多說明請參考 Java 執行緒同步。
執行緒池
使用 ExecutorService 管理執行緒:
import java.util.concurrent.*;
// 固定大小的執行緒池
ExecutorService executor = Executors.newFixedThreadPool(4);
// 提交任務
executor.execute(() -> System.out.println("任務 1"));
executor.execute(() -> System.out.println("任務 2"));
// 有回傳值的任務
Future<String> future = executor.submit(() -> "結果");
String result = future.get();
// 關閉執行緒池
executor.shutdown();
executor.awaitTermination(60, TimeUnit.SECONDS);
常用執行緒池
// 固定大小
ExecutorService fixed = Executors.newFixedThreadPool(4);
// 單一執行緒
ExecutorService single = Executors.newSingleThreadExecutor();
// 快取(按需建立)
ExecutorService cached = Executors.newCachedThreadPool();
// 排程
ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(2);
scheduled.schedule(() -> System.out.println("延遲執行"), 5, TimeUnit.SECONDS);
scheduled.scheduleAtFixedRate(() -> System.out.println("定期執行"), 0, 1, TimeUnit.SECONDS);
更多說明請參考 Java Executor。
volatile
確保變數的可見性:
public class StopThread {
private volatile boolean running = true;
public void run() {
while (running) {
// 執行任務
}
}
public void stop() {
running = false;
}
}
執行緒安全的集合
// 同步包裝
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// 並行集合
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
BlockingQueue<String> queue = new LinkedBlockingQueue<>();
更多說明請參考 Java 並行集合。
完整範例
生產者消費者
import java.util.concurrent.*;
public class ProducerConsumer {
public static void main(String[] args) {
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
// 生產者
Thread producer = new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
queue.put(i);
System.out.println("生產:" + i);
} catch (InterruptedException e) {
break;
}
}
});
// 消費者
Thread consumer = new Thread(() -> {
while (true) {
try {
Integer item = queue.take();
System.out.println("消費:" + item);
} catch (InterruptedException e) {
break;
}
}
});
producer.start();
consumer.start();
}
}
批次處理
ExecutorService executor = Executors.newFixedThreadPool(4);
List<Future<String>> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) {
final int taskId = i;
Future<String> future = executor.submit(() -> {
Thread.sleep(1000);
return "任務 " + taskId + " 完成";
});
futures.add(future);
}
// 等待所有結果
for (Future<String> future : futures) {
System.out.println(future.get());
}
executor.shutdown();
注意事項
- 避免死鎖:注意鎖的順序
- 使用執行緒池:不要直接建立大量執行緒
- 正確處理中斷:檢查 interrupted 狀態
- 使用並行集合:而不是自己同步