標籤:
wait和notify是通過對對象進行鎖,來實現同步和互斥。
wait和notify函數需要在一段的同步代碼中,即在 synchronized的程式碼片段中。
簡單的範例程式碼。
static class TestThread {public Boolean locked = false;public void run() {long last = System.currentTimeMillis();synchronized (locked) {while (locked) {// 釋放這個鎖嗎?try {System.out.println(Thread.currentThread().toString()+ " now is waiting");// 也就是最後測試的結果是,這個wait處如果沒有寫具體時間的話,其他的notify是不會叫醒這裡的鎖的。locked.wait(1000);System.out.println(Thread.currentThread().toString()+ " waiting is end");} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}// System.out.println(Thread.currentThread().toString()// + " lock locked ");locked = true;// work。// System.out.println(Thread.currentThread().toString()// + " work start ");// System.out.println(Thread.currentThread().toString()// + " work start locked" + locked);long now = System.currentTimeMillis();while (now - last < 1000) {locked = true;now = System.currentTimeMillis();}locked = false;// System.out.println(Thread.currentThread().toString()// + " work end notify" );synchronized (locked) {locked.notifyAll();System.out.println(Thread.currentThread().toString()+ " work end notify");}// System.out.println(Thread.currentThread().toString()// + " work finished ");}}/** * @param args */public static void main(String[] args) {final TestThread tt = new TestThread();for (int i = 0; i < 5; i++) {new Thread(new Runnable() {public void run() {tt.run();}}).start();}
輸出結果為:
Thread[Thread-2,5,main] now is waiting
Thread[Thread-3,5,main] now is waiting
Thread[Thread-4,5,main] now is waiting
Thread[Thread-1,5,main] work end notify
Thread[Thread-0,5,main] work end notify
Thread[Thread-2,5,main] waiting is end
Thread[Thread-2,5,main] work end notify
Thread[Thread-3,5,main] waiting is end
Thread[Thread-3,5,main] work end notify
Thread[Thread-4,5,main] waiting is end
Thread[Thread-4,5,main] work end notify
這裡我鎖的是TestThread中的Boolean 對象 locked。通過synchronized (locked) 將locked對象鎖住,但是 locked.wait(1000)又將這個locked對象鎖給釋放了,導致其他線程可以訪問locked對象。然後被釋放的對象被其他線程使用結束後,使用 locked.notifyAll(); 通知其他等待該對象的線程當前對象可以使用。這裡需要注意的地方,一般說明的是wait()的線程都會被提醒並獲得對象鎖再繼續運行,但實際上我測試的結果不是這樣的,如果我這裡沒有設定時間如這裡的1000ms,則當使用notify或notifyAll時,均無法重新啟動線程,所以應該設定一定的時間讓線程自行檢測。
java 多線程中的 wait 和 notify