Java面試題:多線程交替打印字符串


這道題是字節的面試題,當場問我有點緊張沒想出來,只答上來要交替阻塞,還是面試官提醒我用生產者消費者思路解決。

題目

有A類線程50個,任務是打印字符A。有B類線程50個,任務是打印字符B。現在異步啟動這100個線程,問如何才能讓他們交替打印AB字符?

解題思路

設兩個信號SemaphoreA和SemaphoreB,他們代表A類和B類的資源數且他們的上限各有一個。初始設SemaphoreA=1,SemaphoreB=0。當一個A類線程消費完SemaphoreA生產一個B類資源:SemaphoreB++。此時其他A類線程進入阻塞,某一B線程開始獲取資源打印。當一個B類線程消費完SemaphoreB,生產一個A類資源:SemaphoreA++。此后循環交替打印。該題的難點在於是否想到生產者消費者。

實踐

這道題LeetCode上有,我就刷了下:https://leetcode-cn.com/problems/print-foobar-alternately/

描述

兩個不同的線程將會共用一個 FooBar 實例。其中一個線程將會調用 foo() 方法,另一個線程將會調用 bar() 方法。請設計修改程序,以確保 "foobar" 被輸出 n 次。

代碼

 

class FooBar {
    private int n;
    private Semaphore semaphoreFoo = new Semaphore(1);
    private Semaphore semaphoreBar = new Semaphore(0);

    public FooBar(int n) {
        this.n = n;
    }

    public void foo(Runnable printFoo) throws InterruptedException {

        for (int i = 0; i < n; i++) {
            semaphoreFoo.acquire();
            // printFoo.run() outputs "foo". Do not change or remove this line.
            printFoo.run();
            semaphoreBar.release();
        }
    }

    public void bar(Runnable printBar) throws InterruptedException {

        for (int i = 0; i < n; i++) {
            semaphoreBar.acquire();
            // printBar.run() outputs "bar". Do not change or remove this line.
            printBar.run();
            semaphoreFoo.release();
        }
    }
}

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM