今天小編繼續來分享下多線程中的一些內容。
在多線程環境下,由于線程調度的不確定性,所以我們有時候無法很好的去保證其線程的執行順序。
但是呢,我們又要實現這個順序執行,所以我們可以使用到這兩個方法,wait 和 notify
當然,這兩個方法是要在鎖內部進行調用的。
那wait 和 notify 方法是什么呢?
wait?
是使當前執行代碼的線程進行等待。它還具有另一個帶參數的版本:wait(long timeout)
這里的等待,會放進一個等待隊列中。
然后,接著會釋放當前代碼鎖的資源
當滿足一定的條件過后,它會被喚醒,重新去獲取鎖。
那這里的條件呢,有這些:
1.其他線程進行notify()
2.當帶參數的版本中,時間超出了long timeout,也會被喚醒
3.其他線程中,調用本線程的interrupted方法,導致了wait拋出InterruptedException異常
notify
這個方法是喚醒等待的線程。
這里要值得注意的是
1.notify需要在同步方法或者同步塊中使用,因為該方法是去通知可能等待該對象的對象鎖的其他線程,并使它們重新獲取鎖資源。
同步方法:是指synchronized關鍵字修飾的方法。
同步塊:
synchronized(鎖){
}
2.如若是多個線程進行等待,那么此時喚醒線程,也是隨機的,沒有所謂的“先來后到之說”
3.notify方法執行完后,不會立即釋放當前鎖資源,而是還會等到同步方法,或者同步塊執行完。
那來看看這個例子,是如何搭配一起使用的吧
public static void main(String[] args) throws InterruptedException {Object obj=new Object();Thread t=new Thread(()->{synchronized (obj){System.out.println("notify之前");obj.notify();System.out.println("notify之后");}});System.out.println("wait之前");synchronized(obj){t.start();obj.wait();}System.out.println("wait之后");}
代碼結果如下:
wait之前
notify之前
notify之后
wait之后
ok,再次引入一個例子,加深對其的了解吧
比如,我現在要按順序打印A、B、C
那么我們該如何做呢?
我們可以創建三個線程,兩個鎖
A線程,打印A,B線程中等待,C等待B線程
打印完A,那就喚醒B線程
打印完B線程,然后去喚醒C線程。
代碼如下:
public class Demo21 {public static Object locker=new Object();public static Object locker2=new Object();public static void main(String[] args) throws InterruptedException {Thread A=new Thread(()->{System.out.println("A");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (locker){locker.notify();}});Thread B=new Thread(()->{synchronized (locker){try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("B");}synchronized (locker2){locker2.notify();}});Thread C=new Thread(()->{synchronized (locker2){try {locker2.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("C");}});A.start();B.start();C.start();}
}
那么,除了這個notify,還有一個notifyAll
那么這個notifyAll又是什么呢?
notifyAll
notifyAll方法可以一次性喚醒所有的線程等待。
這里值得注意的是,notifyAll多次調用是沒有問題,不會出現報錯
還有,這個是需要同一把鎖,才能全部喚醒
喚醒后,所有線程需要重新獲取鎖,獲取鎖的過程是系統決定,依然是具有不確定性。
ok,那么小編就先分享到這里吧。