概要
我們知道線程是作業系統中一個獨立的個體,在一般多線程環境下,我們希望的是各個線程之間有一定的關聯,使得各個線程組合成一個整體工作。那麼就必須要使線程之間互相能傳遞資訊。這就是線程之間需要通信。線程通信可以采取wait/notify 方法實作通信(當然還有其它通信方式。這節隻學習wait/notify 方法)。
wait/notify定義
1.wait/notify方法定義在Object類中。這說明JAVA中多有對象都擁有wait/notify方法。那麼為什麼wait/notify方法是用來實作線程之間的通信,為何不定義在Thread中呢?首先看一下源碼:
/**The current thread must own this object's monitor. The thread
* releases ownership of this monitor and waits until another thread
* notifies threads waiting on this object's monitor to wake up
* */
public final void wait() throws InterruptedException {
wait();
}
官方文檔中開頭的一段解釋就是,使用wait方法,那麼目前的線程必須要是某個對象的監控者。換句話說,就是要使用wait方法就必須要擁有某個對象的鎖。也就是說wait/notify依賴于對象鎖。而鎖可以是任意一個對象都可以擁有。那麼就意味着必須任意的對象都可以調用wait/notify方法。那麼這些方法就隻能定義在Object中。
**wait/notify使用**
public class ThreadTest3 {
private volatile int i = 0;
public void method1() {
i++;
}
public int getI() {
return i;
}
public static void main(String[] args) {
final ThreadTest3 test3 = new ThreadTest3();
final Object lock = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
for (int k = 0; k < 10; k++) {
test3.method1();
System.out.println("i自增1 ");
if (test3.getI() == 5) {
System.out.println("發出通知。。。。。。");
lock.notify();
}
Thread.currentThread().sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
if(test3.getI() != 5) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("收到通知。。。。。。。。。停止工作");
throw new RuntimeException();
}
}, "t2");
t2.start();
t1.start();
}
}
上述代碼運作結果:
i自增1
i自增1
i自增1
i自增1
i自增1
發出通知。。。。。。
i自增1
i自增1
i自增1
i自增1
i自增1
收到通知。。。。。。。。。停止工作
Exception in thread “t2” java.lang.RuntimeException
at thread.day2.ThreadTest3$2.run(ThreadTest3.java:61)
at java.lang.Thread.run(Thread.java:745)
“`
結果分析:當我們啟動先啟動t2線程時候,擷取了lock的鎖,第一次進去i不等與5,t2調用wait方法進入等待,然後t1擷取lock同步鎖,對i進行自增,在等于5的時候,發出通知調用notify方法。但運作的結果是知道t1運作完成後。t2才執行了停止工作。
結果總結:
1.wait釋放所。并且wait方法是停止目前擁有該對象同步鎖的線程
2.notify不釋放鎖