5

Leetcode 1115 交替打印 FooBar ( Print FooBar Alternately *Medium* ) 题解分析

 2 years ago
source link: https://nicksxs.me/2022/05/01/Leetcode-1115-%E4%BA%A4%E6%9B%BF%E6%89%93%E5%8D%B0-FooBar-Print-FooBar-Alternately-Medium-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Leetcode 1115 交替打印 FooBar ( Print FooBar Alternately *Medium* ) 题解分析

发表于 2022-05-01 分类于 Javaleetcode 阅读次数: 阅读次数: 8 Disqus: 0 Comments
无聊随机了道并发题,还是比较明显的用信号量就可以解决的题,不过第一次做还是有点不适应,要加油多练练

无聊想去 roll 一题就看到了有并发题,就找到了这题,其实一眼看我的想法也是用信号量,但是用 condition 应该也是可以处理的,不过这类问题好像本地有点难调,因为它好像是抽取代码执行的,跟直观的逻辑比较不一样
Suppose you are given the following code:

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");
    }
  }
}

The same instance of FooBar will be passed to two different threads:

  • thread A will call foo(), while
  • thread B will call bar().
    Modify the given program to output "foobar" n times.

Example 1:

Input: n = 1
Output: “foobar”
Explanation: There are two threads being fired asynchronously. One of them calls foo(), while the other calls bar().
“foobar” is being output 1 time.

Example 2:

Input: n = 2
Output: “foobarfoobar”
Explanation: “foobar” is being output 2 times.

其实用信号量是很直观的,就是让打印 foo 的线程先拥有信号量,打印后就等待,给 bar 信号量 + 1,然后 bar 线程运行打印消耗 bar 信号量,再给 foo 信号量 + 1

class FooBar {
    
    private final Semaphore foo = new Semaphore(1);
    private final Semaphore bar = new Semaphore(0);
    private int n;

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

    public void foo(Runnable printFoo) throws InterruptedException {
        
        for (int i = 0; i < n; i++) {
            foo.acquire();
        	// printFoo.run() outputs "foo". Do not change or remove this line.
        	printFoo.run();
            bar.release();
        }
    }

    public void bar(Runnable printBar) throws InterruptedException {
        
        for (int i = 0; i < n; i++) {
            bar.acquire();
            // printBar.run() outputs "bar". Do not change or remove this line.
        	printBar.run();
            foo.release();
        }
    }
}
Buy me a coffee

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK