class Demo extends Thread {
public void run() {
for (int i = 0; i < 60; i++)
System.out.println(Thread.currentThread().getName() + i);
}
}
new Demo().start();
class Demo2 implements Runnable {
public void run() { ... }
}
new Thread(new Demo2()).start();
本質上皆需建立 Thread 實例。Runnable 更彈性,避免單一繼承限制。
start()sleep(), wait(), I/O 等待notify()、I/O 就緒run() 結束、interrupt()、stop()(不建議)關鍵方法:sleep() 需捕捉 InterruptedException;join() 使呼叫執行緒等待目標執行緒結束(異步變同步)。
多執行緒操作共享資料,指令非原子性導致資料競爭。
synchronized (lockObject) {
// 臨界區
}
public synchronized void saleTicket() { ... }
// 非靜態鎖 this,靜態鎖 Class 物件
class Ticket implements Runnable {
private int ticket = 400;
public void run() {
while (true) {
synchronized (this) {
if (ticket <= 0) break;
System.out.println(Thread.currentThread().getName() + "---賣出" + ticket--);
}
}
}
}
必須在同一把鎖(synchronized 同一物件)內呼叫。
synchronized (p) {
if (flag) p.wait(); // 等待
// 生產/消費邏輯
flag = !flag;
p.notifyAll(); // 喚醒所有等待執行緒
}
class Goods {
private String name; private int num; private boolean flag = false;
public synchronized void produce(String name) {
while (flag) wait();
this.name = name + "編號:" + num++;
System.out.println(Thread.currentThread().getName() + "生產了..." + this.name);
flag = true; notifyAll();
}
public synchronized void consume() {
while (!flag) wait();
System.out.println(Thread.currentThread().getName() + "消費了*****" + name);
flag = false; notifyAll();
}
}
// 啟動 2 生產者 + 2 消費者
輸出顯示嚴格交替生產消費,驗證同步正確性。