太原Java后端開(kāi)發(fā)??济嬖囶}有哪些?

 

太原Java后端開(kāi)發(fā)??济嬖囶}有哪些?

 

太原Java后端開(kāi)發(fā)常考面試題有哪些?今天小編給大家分享一位小伙伴在面試時(shí)遇到的多個(gè)線程順序執(zhí)行的面試題,希望能幫助到大家。

近日有學(xué)生在參加某公司校招面試時(shí),遇到一個(gè)多個(gè)線程順序執(zhí)行的面試題,特意記錄下來(lái)和大家分享一下,這個(gè)題目的具體要求是這樣的:

假設(shè)有3個(gè)線程 a,b,c,要求三個(gè)線程一起進(jìn)入到就緒態(tài),執(zhí)行時(shí)一定要按照 a-->b-->c的順序執(zhí)行。即使a或者b線程進(jìn)入到了阻塞態(tài),也一定會(huì)按照a-->b-->c的順序運(yùn)行線程。請(qǐng)問(wèn)該如何保證實(shí)現(xiàn)這個(gè)需求呢?

解決方案

關(guān)于這道題,網(wǎng)上常見(jiàn)的實(shí)現(xiàn)思路,大致有4種解決方案:

  1. 通過(guò)join()方法使當(dāng)前線程“阻塞”,等待指定線程執(zhí)行完畢后繼續(xù)執(zhí)行;
  2. 通過(guò)倒數(shù)計(jì)時(shí)器CountDownLatch實(shí)現(xiàn);
  3. 通過(guò)創(chuàng)建單一化線程池 newSingleThreadExecutor()實(shí)現(xiàn);
  4. 通過(guò)ReentrantLock 中的條件變量實(shí)現(xiàn);

今天先使用ReentrantLock 的條件變量來(lái)實(shí)現(xiàn)這個(gè)題目中的需求。

 使用ReentrantLock 條件變量

首先咱們來(lái)了解一下,什么是ReentrantLock 條件變量(Condition)。

ReentrantLock 中的條件變量功能,類似于普通 synchronized 的 wait、notify,我們可以使用Reentrantlock 鎖,配合 Condition 對(duì)象上的 await()和 signal()或 signalAll()方法,來(lái)實(shí)現(xiàn)線程間協(xié)作。與synchronized的wait和notify不同之處在于,ReentrantLock中的條件變量可以有多個(gè),可以實(shí)現(xiàn)更精細(xì)的控制線程。

Condition中常用的方法API有如下這些:

太原Java后端開(kāi)發(fā)??济嬖囶}有哪些?

ReentrantLock代碼實(shí)現(xiàn):

class ShareDataLock{
    // 線程執(zhí)行的條件 1:線程1執(zhí)行 2:線程2執(zhí)行 3:線程3執(zhí)行
    int number =1;
    // 鎖
    Lock lock = new ReentrantLock();
    // 從鎖中獲得3個(gè)條件變量
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();

    // 第一個(gè)線程run之后執(zhí)行的方法
    public void f1(){
        lock.lock();
        try {
            // 如果條件值不為1 就掛起等待
            while(number!=1){
                condition1.await();
            }
            // 故意阻塞100毫秒,看看其他的線程會(huì)不會(huì)不再排隊(duì)
            Thread.sleep(100);
            System.out.println("------1--------");
            // 線程1 執(zhí)行完畢 把變量設(shè)置為2
            number = 2;
            // 喚醒第2個(gè)條件變量
            condition2.signal();
        } catch (Exception e) {
          e.printStackTrace();
        } finally {
            // 不管拋沒(méi)拋出異常都要解鎖,防止線程死鎖
          lock.unlock();
        }
    }
    
    public void f2(){
        lock.lock();
        try {
            while(number!=2){
                condition2.await();
            }
            System.out.println("------2--------");
            number = 3;
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    
    public void f3(){
        lock.lock();
        try {
            while(number!=3){
                condition3.await();
            }
            System.out.println("------3--------");
            number = 1;
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

public class SynchronizedAndReentrantLockDemo {

    public static void main(String[] args) {
        ShareDataLock shareDataLock = new ShareDataLock();
        for (int i = 0; i < 10; i++) {
            // 3個(gè)線程分別執(zhí)行1,2,3 3個(gè)方法 ,并且同時(shí)就緒
            new Thread(()->shareDataLock.f1(),"AA").start();
            new Thread(()->shareDataLock.f2(),"bb").start();
            new Thread(()->shareDataLock.f3(),"cc").start();
        }

    }
}
代碼執(zhí)行效果如下圖:
太原Java后端開(kāi)發(fā)??济嬖囶}有哪些?

 

現(xiàn)在我們就會(huì)發(fā)現(xiàn),3個(gè)線程已經(jīng)可以被隨意控制了,你會(huì)了嗎?

如上文所述,讓多個(gè)線程按順序執(zhí)行,網(wǎng)上常見(jiàn)的解決方案有4種。但大家要注意的是,面試官出這個(gè)題有一個(gè)先決條件,“要讓所有的線程同時(shí)就緒”,所以我們就可以排除使用join方法和使用單一化線程池的方案了。那么要想實(shí)現(xiàn)這個(gè)面試題中的需求,比較靠譜的方法只剩下ReentrantLock 中的條件變量和使用倒數(shù)計(jì)時(shí)器CountDownLatch兩種方案了。

太原千鋒IT培訓(xùn)

太原千鋒教育成立教研學(xué)科中心,推出貼近企業(yè)需求的線下技能培訓(xùn)課程。課程包含:HTML5大前端培訓(xùn)、Java+分布式開(kāi)發(fā)培訓(xùn)、Python人工智能+數(shù)據(jù)分析培訓(xùn)、全領(lǐng)域?qū)崙?zhàn)UI/UE設(shè)計(jì)設(shè)計(jì)培訓(xùn)、云計(jì)算培訓(xùn)、全棧軟件測(cè)試培訓(xùn)、大數(shù)據(jù)+人工智能培訓(xùn)、智能物聯(lián)網(wǎng)+嵌入式培訓(xùn)、Unity游戲開(kāi)發(fā)培訓(xùn)、網(wǎng)絡(luò)安全培訓(xùn)、區(qū)塊鏈培訓(xùn)、影視剪輯包裝培訓(xùn)、游戲原畫培訓(xùn)、全媒體運(yùn)營(yíng)培訓(xùn)。采用全程面授高品質(zhì)、高體驗(yàn)培養(yǎng)模式,學(xué)科大綱緊跟企業(yè)需求,擁有國(guó)內(nèi)一體化教學(xué)管理及學(xué)員服務(wù),在職業(yè)教育發(fā)展道路上不斷探索前行。

小店校區(qū)

山西省太原小店長(zhǎng)治路230號(hào)能源互聯(lián)網(wǎng)大廈6層

 



有問(wèn)必答,專業(yè)學(xué)習(xí)規(guī)劃師為您免費(fèi)咨詢解答
課程底價(jià)、品牌對(duì)比、師資力量、學(xué)習(xí)時(shí)間、課程內(nèi)容、報(bào)考政策...想了解什么?就來(lái)咨詢學(xué)習(xí)規(guī)劃師吧!
以上就是太原千鋒IT培訓(xùn)給大家整理的太原Java后端開(kāi)發(fā)??济嬖囶}有哪些?。如需了解更多太原Java后端開(kāi)發(fā)常考面試題有哪些?相關(guān)信息,可以咨詢?cè)诰€客服了解咨詢。

評(píng)論 丨 共0個(gè)

 
 

登錄后發(fā)表評(píng)論
評(píng)論
 
 
預(yù)約試聽(tīng)