多個線程順序打印問題

三個線程分別打印A,B捐下,C持舆,要求這三個線程一起運行嘲碱,打印n次,輸出形如“ABCABCABC....”的字符串理卑。

1. 解法一:使用Lock

public class PrintABCUsingLock {
    private int times;
    private int state;
    private Lock lock = new ReentrantLock();

    public PrintABCUsingLock(int times) {
        this.times = times;
    }

    public static void main(String[] args) {
        PrintABCUsingLock printABC = new PrintABCUsingLock(10);
        new Thread(printABC::printA).start();
        new Thread(printABC::printB).start();
        new Thread(printABC::printC).start();
    }

    public void printA() {
        print("A", 0);
    }

    public void printB() {
        print("B", 1);
    }

    public void printC() {
        print("C", 2);
    }

    private void print(String name, int targetState) {
        for (int i = 0; i < times;) {
            lock.lock();
            if (state % 3 == targetState) {
                state++;
                i++;
                System.out.print(name);
            }
            lock.unlock();
        }
    }
}

2. 解法二:使用wait/notify

public class PrintABCUsingWaitNotify {
    private int times;
    private volatile int state;
    private static final Object LOCK = new Object();

    public PrintABCUsingWaitNotify(int times) {
        this.times = times;
    }

    public static void main(String[] args) {
        PrintABCUsingWaitNotify printABC = new PrintABCUsingWaitNotify(10);
        new Thread(printABC::printA).start();
        new Thread(printABC::printB).start();
        new Thread(printABC::printC).start();
    }

    public void printA() {
        try {
            print("A", 0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void printB() {
        try {
            print("B", 1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void printC() {
        try {
            print("C", 2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void print(String name, int targetState)
            throws InterruptedException {
        for (int i = 0; i < times; i++) {
            synchronized (LOCK) {
                while (state % 3 != targetState) {
                    LOCK.wait();
                }
                state++;
                System.out.print(name);
                LOCK.notifyAll();
            }
        }
    }
}

解法三:使用Lock/Condition

public class PrintABCUsingLockCondition {
    private int times;
    private int state;
    private Lock lock = new ReentrantLock();
    private Condition conditionA = lock.newCondition();
    private Condition conditionB = lock.newCondition();
    private Condition conditionC = lock.newCondition();

    public PrintABCUsingLockCondition(int times) {
        this.times = times;
    }

    public static void main(String[] args) {
        PrintABCUsingLockCondition printABC = new PrintABCUsingLockCondition(10);
        new Thread(printABC::printA).start();
        new Thread(printABC::printB).start();
        new Thread(printABC::printC).start();
    }

    public void printA() {
        print("A", 0, conditionA, conditionB);
    }

    public void printB() {
        print("B", 1, conditionB, conditionC);
    }

    public void printC() {
        print("C", 2, conditionC, conditionA);
    }

    private void print(String name, int targetState, Condition current,
            Condition next) {
        for (int i = 0; i < times;) {
            lock.lock();
            try {
                while (state % 3 != targetState) {
                    current.await();
                }
                state++;
                i++;
                System.out.print(name);
                next.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
}

解法四:使用Semaphore

public class PrintABCUsingSemaphore {
    private int times;
    private Semaphore semaphoreA = new Semaphore(1);
    private Semaphore semaphoreB = new Semaphore(0);
    private Semaphore semaphoreC = new Semaphore(0);

    public PrintABCUsingSemaphore(int times) {
        this.times = times;
    }

    public static void main(String[] args) {
        PrintABCUsingSemaphore printABC = new PrintABCUsingSemaphore(10);
        new Thread(printABC::printA).start();
        new Thread(printABC::printB).start();
        new Thread(printABC::printC).start();
    }

    public void printA() {
        try {
            print("A", semaphoreA, semaphoreB);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void printB() {
        try {
            print("B", semaphoreB, semaphoreC);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void printC() {
        try {
            print("C", semaphoreC, semaphoreA);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void print(String name, Semaphore current, Semaphore next)
            throws InterruptedException {
        for (int i = 0; i < times; i++) {
            current.acquire();
            System.out.print(name);
            next.release();
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子扇单,更是在濱河造成了極大的恐慌,老刑警劉巖奠旺,帶你破解...
    沈念sama閱讀 212,657評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜘澜,死亡現(xiàn)場離奇詭異,居然都是意外死亡响疚,警方通過查閱死者的電腦和手機鄙信,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,662評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忿晕,“玉大人装诡,你說我怎么就攤上這事〖危” “怎么了鸦采?”我有些...
    開封第一講書人閱讀 158,143評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長咕幻。 經(jīng)常有香客問我渔伯,道長,這世上最難降的妖魔是什么肄程? 我笑而不...
    開封第一講書人閱讀 56,732評論 1 284
  • 正文 為了忘掉前任锣吼,我火速辦了婚禮选浑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吐限。我一直安慰自己鲜侥,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,837評論 6 386
  • 文/花漫 我一把揭開白布诸典。 她就那樣靜靜地躺著描函,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狐粱。 梳的紋絲不亂的頭發(fā)上舀寓,一...
    開封第一講書人閱讀 50,036評論 1 291
  • 那天,我揣著相機與錄音肌蜻,去河邊找鬼互墓。 笑死,一個胖子當(dāng)著我的面吹牛蒋搜,可吹牛的內(nèi)容都是我干的篡撵。 我是一名探鬼主播,決...
    沈念sama閱讀 39,126評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼豆挽,長吁一口氣:“原來是場噩夢啊……” “哼育谬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起帮哈,我...
    開封第一講書人閱讀 37,868評論 0 268
  • 序言:老撾萬榮一對情侶失蹤膛檀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后娘侍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咖刃,經(jīng)...
    沈念sama閱讀 44,315評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,641評論 2 327
  • 正文 我和宋清朗相戀三年憾筏,在試婚紗的時候發(fā)現(xiàn)自己被綠了嚎杨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,773評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡氧腰,死狀恐怖磕潮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情容贝,我是刑警寧澤自脯,帶...
    沈念sama閱讀 34,470評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站斤富,受9級特大地震影響膏潮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜满力,卻給世界環(huán)境...
    茶點故事閱讀 40,126評論 3 317
  • 文/蒙蒙 一焕参、第九天 我趴在偏房一處隱蔽的房頂上張望轻纪。 院中可真熱鬧,春花似錦叠纷、人聲如沸刻帚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,859評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崇众。三九已至,卻和暖如春航厚,著一層夾襖步出監(jiān)牢的瞬間顷歌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,095評論 1 267
  • 我被黑心中介騙來泰國打工幔睬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留眯漩,地道東北人。 一個月前我還...
    沈念sama閱讀 46,584評論 2 362
  • 正文 我出身青樓麻顶,卻偏偏與公主長得像赦抖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子辅肾,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,676評論 2 351

推薦閱讀更多精彩內(nèi)容