線程安全
常用方法
只能在同步控制方法或同步控制塊裏面調用 wait()、notify()、notifyAll()。如果在非同步控制塊中調用這些方法,能通過編譯但運行會出錯,得到IllegalMonitorStateException異常。
當調用某個ExecutorService的shutdownNow()時,它會調用 所有 由它控制的 線程的interrupt()。
調用wait()時,執行兩個動作:掛起線程,釋放鎖。
別的地方調用notifyAll(),將喚醒wait()所掛起的線程。在線程繼續運行之前將重新獲得上次wait()調用時釋放的鎖。
使用notify()時,在衆多等待同一個鎖的任務中只有一個會被喚醒。
notifyAll()喚醒所有等待同一個鎖的任務。注意,這並不意味着在程序的任何地方,任何被wait()掛起的線程都會被喚醒,。當notifyAll()因爲某個特定鎖而被調用時,只有等待這個鎖的任務纔會被喚醒。
//wait() notify()全放在Car類中處理 import java.util.concurrent.*; class Car { private boolean waxOn = false; // true表示打完蠟該拋光了 public synchronized void wax() throws InterruptedException { while (waxOn == true) wait(); TimeUnit.MILLISECONDS.sleep(100); waxOn = true; System.out.println("waxed!"); notifyAll(); } public synchronized void buff() throws InterruptedException { while (waxOn != true) wait(); TimeUnit.MILLISECONDS.sleep(100); waxOn = false; System.out.println("buffed!"); notifyAll(); } } class Wax implements Runnable { private Car car; public Wax(Car car) { this.car = car; } public void run() { try { while (!Thread.interrupted()) { car.wax(); } } catch (InterruptedException e) { System.out.println("Wax Exiting via interrupt"); } } } class Buff implements Runnable { private Car car; public Buff(Car car) { this.car = car; } public void run() { try { while (!Thread.interrupted()) { car.buff(); } } catch (InterruptedException e) { System.out.println("Buff Exiting via interrupt"); } } } public class WaxOMatic { public static void main(String[] args) throws Exception { ExecutorService exec = Executors.newCachedThreadPool(); Car car = new Car(); exec.execute(new Buff(car)); exec.execute(new Wax(car)); TimeUnit.SECONDS.sleep(1); // Run for a while... exec.shutdownNow(); // Interrupt all tasks } } /* waxed! buffed! waxed! buffed! waxed! buffed! waxed! buffed! waxed! buffed! Wax Exiting via interrupt Buff Exiting via interrupt */
|