三種方法教你實現多線程交替打印ABC,干貨滿滿!
1.問題背景
假設有三個線程,分別打印字母A、B、C。我們需要讓這三個線程交替運行,按順序打印出“ABCABCABC...”,直到打印一定次數或者滿足某個條件。如何通過多線程的協調實現這個任務呢?這聽起來簡單,實際涉及到線程之間的同步和互斥,是我們學習多線程編程的一個很好的練習。
2.多線程編程的挑戰
在多線程編程中,最大的問題就是如何控制多個線程的執行順序。線程是并發執行的,也就是說它們的執行順序在沒有約束的情況下是不可預知的。為了確保多個線程按照我們期望的順序執行,就需要使用一些同步機制,比如鎖、條件變量、信號量等。
接下來,我會帶大家用三種方式來實現這個任務。我們會分別使用Object的wait()和notify()方法、ReentrantLock與Condition、以及信號量來實現多線程交替打印ABC。
3.方案一:使用wait()和notify()
首先,最常用的一種方法是利用Java中Object類自帶的wait()和notify()方法來實現線程之間的同步。每個線程在完成它的打印任務后,通知下一個線程開始執行。
實現步驟
- 定義一個共享對象用來同步。
- 使用wait()讓線程進入等待狀態。
- 使用notify()喚醒下一個線程。
實現代碼:
圖片
運行結果:
圖片
在這個實現中,我們使用了wait()和notifyAll()方法來控制線程的執行順序。每個線程在不該自己執行的時候調用wait()方法進入等待狀態,直到被下一個線程通過notifyAll()方法喚醒。
4.方案二:使用ReentrantLock和Condition
第二種方法是使用ReentrantLock和Condition類。ReentrantLock是Java中更高級的鎖機制,可以控制多個條件變量,而Condition則可以用來替代wait()和notify()的功能。
實現步驟
- 定義一個ReentrantLock和多個Condition。
- 每個線程等待相應的Condition,當符合條件時打印字符并喚醒下一個線程。
實現代碼
圖片
圖片
運行結果:
圖片
在這個實現中,我們使用ReentrantLock和Condition來替代了wait()和notify()。通過lock來確保線程安全,通過Condition來控制每個線程的執行順序。
5.方案三:使用信號量
最后一種方法是使用Semaphore類。Semaphore是一個計數信號量,可以控制多個線程之間的協調。這里,我們使用三個信號量,分別控制線程A、B、C的執行。
實現步驟
定義三個信號量semA、semB、semC。
每個線程在自己的信號量上等待,打印完成后釋放下一個線程的信號量。
實現代碼
圖片
圖片
運行結果:
圖片
在這個實現中,信號量控制了線程的執行順序。初始時,semA的計數為1,而semB和semC為0,這保證了線程A先運行,然后通過釋放信號量來依次喚醒線程B和C。
今天我們學習了三種實現多線程交替打印ABC的方法:使用wait()和notify(),使用ReentrantLock和Condition,以及使用信號量。通過這些方法,我們可以有效地控制線程之間的同步與互斥,解決復雜的并發問題。
這三種方法各有優劣。wait()和notify()較為基礎,適合簡單的場景;ReentrantLock和Condition提供了更細粒度的控制,適合復雜的并發場景;而Semaphore則是一種經典的計數信號量機制,在某些場景下顯得更加直觀和高效。