多個執行緒交替列印
阿新 • • 發佈:2020-11-24
wait和notify實現
注意點
1、wait方式是讓當前持有鎖的執行緒進入等待佇列(不是阻塞佇列),呼叫了wait方法後,當前執行緒就不會執行wait之後的程式碼邏輯了,所以notify方法必須在wait方法之前。
等待佇列和阻塞佇列的區別
對於每個物件來說,都有自己的等待佇列和阻塞佇列。
2、需要在迴圈結束後,加上notify,因為當其中一個執行緒正常執行完後,另一個執行緒一定還處於等待佇列,所以最後需要被喚醒,如果不寫,則雖然能正常打印出結果,但是程式不會結束。
3、要保證兩個執行緒的開始順序,因為thread.start方法,並不是先呼叫就一定是先呼叫的執行緒先執行,所以可以用countdownlatch來保證列印順序的開始。
/** * 執行緒交替列印 */ public class Demo01 { public static void main(String[] args) { //兩個執行緒分別來列印這兩個陣列 char[] arr1 = {'1', '2', '3', '4'}; char[] arr2 = {'a', 'b', 'c', 'd'}; //門閂,用於保證其中一個執行緒一定會先執行 CountDownLatch latch = new CountDownLatch(1); //鎖資源 Object lock = new Object(); new Thread(() -> { try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock) { for (char c : arr1) { System.out.println(c); //必須要先使用notify lock.notify(); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //最後需要加上notify,防止另一個執行緒永遠處於wait狀態,程式不能正常介紹 lock.notify(); } }).start(); new Thread(() -> { synchronized (lock) { for (char c : arr2) { System.out.println(c); if (latch.getCount() != 0L) latch.countDown(); lock.notify(); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } lock.notify(); } }).start(); } }