試試,阿里P7的筆試題:多執行緒按序列印如何實現?
阿新 • • 發佈:2020-11-28
下面是阿里 P7 的一道筆試題,公眾號【Java鬥帝】內回覆666有免費電子書贈送
1、題目
編寫一個程式,開啟 3 個執行緒,這 3 個執行緒的 ID 分別為 A、B、C,3 個執行緒交替列印 1-100 的整數,樣例 Sample:
Thread1:1 Thread2:2 Thread3:3 Thread1:4 Thread2:5 Thread3:6 .... Thread3:99 Thread1:100
大家可以先思考一下,試試看看能否實現?
2、解題思路
題目中要求 3 個執行緒啟動之後,需要按順序一個接著一個來執行,重點是 3 個執行緒都處於執行狀態,如何能讓他們按順序來列印?
大家可以把 3 個執行緒想象為 3 個人(ABC),ABC 3 個人手拉手組成一個環,然後 3 個人都坐那等通知,等誰的通知呢,等待上一個人的通知,B 等待 A 的通知,C 等待 B 的通知,A 等待 C 的通知。
剛開始:程式先喚起 A,A 列印之後,通知 B,然後 A 進入休眠等待喚醒通知,此時輪到 B 列印了,B 列印之後通知 C,B 進入休眠等待喚醒通知,此時輪到 C 列印了,C 列印之後通知 A,C 進入休眠等待喚醒通知,通過這種方式來實現,每個執行緒列印之後,負責喚醒下一個執行緒,然後自己進入休眠狀態。
關鍵技術點有 2 個:
1、阻塞執行緒
2、喚起執行緒
java.util.concurrent.locks.LockSupport類剛好提供了 2 個靜態方法支援這些操作
1、park():讓當前執行緒阻塞
2、unpark(Thread thread):用來喚起阻塞中的執行緒
3、答案
程式碼相當簡單。
import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.LockSupport; public class ThreadTest { static List<Thread> threadList = new ArrayList<>();//存放執行緒的集合 static int threadSize = 3;//總共多少個執行緒 static int threadIndex = 0;//當前執行緒下標 static int maxValue = 100;//需要輸出的數的最大值 static int curValue = 1;//數的當前值 public static void main(String[] args) throws InterruptedException { //建立執行緒 for (int i = 1; i <= threadSize; i++) { Thread thread = new Thread(() -> { while (true) { //阻塞當前執行緒 LockSupport.park(); //當前的值需要小於最大值 if (curValue <= maxValue) { System.out.println(Thread.currentThread().getName() + ":" + curValue++); } else { break; } //喚起下一個執行緒 LockSupport.unpark(threadList.get(++threadIndex % threadList.size())); } //喚起所有執行緒 threadList.forEach(LockSupport::unpark); }); thread.setName(String.format("Thread%d", i)); threadList.add(thread); } //啟動所有執行緒 for (Thread thread : threadList) { thread.start(); } //喚起第一個執行緒 LockSupport.unpark(threadList.get(0)); } }
推薦閱讀
為什麼阿里巴巴的程式設計師成長速度這麼快,看完他們的內部資料我懂了
看完三件事❤️
如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
關注公眾號 『 Java鬥帝 』,不定期分享原創知識。
同時可以期待後續文章ing