LeetCode - 交替打印FooBar

題目鏈接:https://leetcode-cn.com/problems/print-foobar-alternately/

題目描述

我們提供一個類:

class FooBar {
  public void foo() {
    for (int i = 0; i < n; i++) {
      print("foo");
    }
  }

  public void bar() {
    for (int i = 0; i < n; i++) {
      print("bar");
    }
  }
}

兩個不同的線程將會共用一個 FooBar 實例。其中一個線程將會調用 foo() 方法,另一個線程將會調用 bar() 方法。

請設計修改程序,以確保 “foobar” 被輸出 n 次。

示例1:

輸入: n = 1
輸出: “foobar”
解釋: 這裏有兩個線程被異步啓動。其中一個調用 foo() 方法, 另一個調用 bar() 方法,“foobar” 將被輸出一次。

示例2:

輸入: n = 2
輸出: “foobarfoobar”
解釋: “foobar” 將被輸出l兩次。

我的思路

  • 最近練練多線程編程,這道題是比較簡單但很經典的多線程題目。
  • 題目需要交替打印 foo 和 bar 兩個字符串,意思是隻有其中一個打印完畢,才能且只能打印另外一個字符串。
  • 控制兩個字符串的打印,需要用到兩個互斥鎖,one 和 two。
  • 在即將打印 foo 前,需要鎖住 one,意思是打印完 foo,只能去打印 bar,不能還打印 foo,保證了不會出現類似 foofoobarbar 這種結果。此時 one 和 two 都被已經鎖住,因此保證了打印 foo 中不能打印任意字符。打印完解鎖 two,意思是打印完 foo 才能去打印 bar。
  • 同樣的道理,對於打印 bar 字符的互斥鎖處理是一樣的。
  • 這倆個互斥鎖的使用看似簡單,實際上還是有很多思考在裏面。
class FooBar {
private:
    int n;
    std::mutex one;
    std::mutex two;
public:
    FooBar(int n) {
        this->n = n;
        two.lock();
    }

    void foo(function<void()> printFoo) {
        
        for (int i = 0; i < n; i++) {
            one.lock();		//鎖“自己”,保證打印完不會再打印“自己”,除非 bar 打印完
            printFoo();
            two.unlock();	//解鎖 bar,使得只有“自己”打印完,才能去打印 bar
        }
    }

    void bar(function<void()> printBar) {
        
        for (int i = 0; i < n; i++) {
            two.lock();		//鎖“自己”,保證打印完不會再打印“自己”,除非 foo 打印完
            printBar();
            one.unlock();	//解鎖 foo,使得只有“自己”打印完,才能去打印 foo 
        }
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章