請編寫一個程式,使用兩個線程分別輸出數字和字母,要求輸出的結果為:1A2B3C4D5E6F7G8H9I10J。 提示:可以使用Java中的wait()和notify()方法來實現線程間的通信。 public class NumberLetterPrinter { // 定義一個靜態的鎖對象 priv ...
請編寫一個程式,使用兩個線程分別輸出數字和字母,要求輸出的結果為:1A2B3C4D5E6F7G8H9I10J。
提示:可以使用Java中的wait()和notify()方法來實現線程間的通信。
public class NumberLetterPrinter { // 定義一個靜態的鎖對象 private static final Object lock = new Object(); // 定義一個計數器變數 private static volatile int count = 1; public static void main(String[] args) { // 創建第一個線程,輸出數字 new Thread(() -> { // 使用同步塊,鎖定鎖對象 synchronized (lock) { // 當計數器變數小於等於10時,一直迴圈輸出數字 while (count <= 10) { // 輸出數字並將計數器變數加1 System.out.print(count++); try { // 喚醒另一個線程併進入等待狀態 lock.notify(); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 退出迴圈後,釋放鎖對象 lock.notify(); } }).start(); // 創建第二個線程,輸出字母 new Thread(() -> { // 使用同步塊,鎖定鎖對象 synchronized (lock) { // 當計數器變數小於等於10時,一直迴圈輸出字母 while (count <= 10) { // 輸出字母並將計數器變數加1 System.out.print((char) (count + 64)); try { // 喚醒另一個線程併進入等待狀態 lock.notify(); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 退出迴圈後,釋放鎖對象 lock.notify(); } }).start(); } }
代碼執行流程如下:
-
程式啟動後,創建了兩個線程分別輸出數字和字母。
-
兩個線程都使用了同步塊,並鎖定了同一個靜態的鎖對象
lock
,以保證線程安全。 -
第一個線程進入迴圈後,判斷計數器變數
count
是否小於等於10。由於count
初始值為1,因此第一次進入迴圈。 -
第一個線程輸出數字並將計數器變數加1。此時
count
變數為2。 -
第一個線程調用
lock.notify()
方法喚醒第二個線程,然後調用lock.wait()
方法進入等待狀態。 -
第二個線程被喚醒後,進入同步塊,判斷計數器變數
count
是否小於等於10。由於count
變數為2,因此進入迴圈。 -
第二個線程輸出字母並將計數器變數加1。此時
count
變數為3。 -
第二個線程調用
lock.notify()
方法喚醒第一個線程,然後調用lock.wait()
方法進入等待狀態。 -
第一個線程被喚醒後,進入同步塊,判斷
-
計數器變數
count
此時為3,因此第一個線程進入迴圈,輸出數字3並將計數器變數加1。此時count
變數為4。 -
第一個線程調用
lock.notify()
方法喚醒第二個線程,然後調用lock.wait()
方法進入等待狀態。 -
第二個線程被喚醒後,進入同步塊,判斷計數器變數
count
是否小於等於10。由於count
變數為4,因此進入迴圈。 -
第二個線程輸出字母並將計數器變數加1。此時
count
變數為5。 -
第二個線程調用
lock.notify()
方法喚醒第一個線程,然後調用lock.wait()
方法進入等待狀態。 -
第一個線程被喚醒後,進入同步塊,以此類推,直到迴圈輸出數字和字母的次數都達到10次為止。
-
兩個線程都執行完迴圈後,程式結束。
總體來說,這段代碼的執行流程可以看作是兩個線程交替輸出數字和字母,直到迴圈次數達到10次為止。其中,使用了同步塊和鎖對象來保證線程安全,使用wait()
和notify()
方法來實現線程之間的通信。