1. 程式人生 > 實用技巧 >多個執行緒交替列印

多個執行緒交替列印

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();

    }

}