試試,阿里P7的筆試題:多按序打印如何實現?

下面是阿里 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));
    }
}

推薦閱讀

爲何阿里巴巴的程序員成長速度這麼快,看完他們的內部資料我懂了

程序員達到50W年薪所須要具有的知識體系。

—小時解讀併發編程三大特性

關於【暴力遞歸算法】你所不知道的思路

看完三件事❤️

若是你以爲這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:

點贊,轉發,有大家的 『點贊和評論』,纔是我創造的動力。

關注公衆號 『 Java鬥帝 』,不按期分享原創知識。

同時能夠期待後續文章ing🚀

相關文章
相關標籤/搜索