public class MyThread extends Thread {
@Override
public void run() {
// 線程執行邏輯
}
}
啟動:new MyThread().start();
public class MyRunnable implements Runnable {
@Override
public void run() {
// 線程執行邏輯
}
}
啟動:new Thread(new MyRunnable()).start();
優點:避免單繼承限制,方便共享資源,支援線程池。
start():啟動新線程,由 JVM 呼叫 run()。run(),否則會在當前線程同步執行,失去多線程意義。new Thread() 後,尚未呼叫 start()。start() 後,等待 CPU 排程。run() 方法。sleep()、wait()、I/O、鎖等待而暫停執行。run() 結束或拋出未捕獲異常。狀態轉換圖:新建 → 就緒 ↔ 執行 → 阻塞 → 就緒 → 執行 → 終止
setPriority(int) 範圍 1~10,預設 5。高優先級線程獲得 CPU 機率較大,但非絕對。
Thread.sleep(long millis) 讓當前線程放棄 CPU 進入阻塞,指定時間後自動轉就緒。
Thread.yield() 讓當前線程從執行態回到就緒態,僅讓給同優先級或更高優先級線程。
join() 使當前線程等待目標線程終止後再繼續。
Thread t1 = new Thread(() -> { ... });
t1.start();
t1.join(); // 主線程等待 t1 結束
當多線程同時讀寫共享變數時,會產生資料不一致。Java 提供 synchronized 關鍵字實現互斥鎖。
class Counter implements Runnable {
private int count = 0;
public void run() {
for (int i = 0; i < 10; i++) {
count++;
Thread.yield();
count--;
System.out.println(count);
}
}
}
public class Test {
public static void main(String[] args) {
Counter c = new Counter();
new Thread(c).start();
new Thread(c).start();
}
}
// 輸出結果混亂,出現非零值
class SafeCounter implements Runnable {
private int count = 0;
public synchronized void run() { // 或 synchronized(this) 區塊
for (int i = 0; i < 10; i++) {
count++;
Thread.yield();
count--;
System.out.println(count); // 全部輸出 0
}
}
}
關鍵點: 同步鎖對象必須是共享資源所屬的實例(或共享的鎖對象),確保同一時間只有一個線程進入臨界區。