下面是阿里 P7 的一道筆試題,公衆號【Java鬥帝】內回覆666有免費電子書贈送java
編寫一個程序,開啓 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
你們能夠先思考一下,試試看看可否實現?算法
題目中要求 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 進入休眠等待喚醒通知,經過這種方式來實現,每一個線程打印以後,負責喚醒下一個線程,而後本身進入休眠狀態。ide
關鍵技術點有 2 個:spa
一、阻塞線程.net
二、喚起線程線程
java.util.concurrent.locks.LockSupport類恰好提供了 2 個靜態方法支持這些操做code
一、park():讓當前線程阻塞
二、unpark(Thread thread):用來喚起阻塞中的線程
代碼至關簡單。
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🚀