LeetCode1115题地址:https://leetcode-cn.com/problems/print-in-order/
LeetCode刷题:1115. 交替打印 FooBar
给你一个类:
class FooBar {
private int n;
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
printFoo.run();
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
printBar.run();
}
}
}
两个不同的线程将会共用一个 FooBar 实例:
- 线程 A 将会调用 foo() 方法,而
- 线程 B 将会调用 bar() 方法
请设计修改程序,以确保 “foobar” 被输出 n 次(提示:1 <= n <= 1000)。
示例 1:
输入:n = 1
输出:"foobar"
解释:这里有两个线程被异步启动。其中一个调用 foo() 方法, 另一个调用 bar() 方法,"foobar" 将被输出一次。
示例 2:
输入:n = 2
输出:"foobarfoobar"
解释:"foobar" 将被输出两次。
synchronized? + ?flag标志位? + ?wait / notify:
思路:设置一个标志flag,在两个方法内交替改变flag的值,然后通过wait / notify控制交替打印
class FooBar {
private static Object lock = new Object();
private int flag = 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++) {
synchronized (lock) {
if (flag != 0) {
lock.wait();
}
printFoo.run();
flag = 1;
lock.notify();
}
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
synchronized (lock) {
if (flag != 1) {
lock.wait();
}
printBar.run();
flag = 0;
lock.notify();
}
}
}
}
信号量 Semaphore:
思路:创建两个信号量 Semaphore,在两个方法内交替获取 / 释放,实现交替打印
class FooBar {
private int n;
private Semaphore foo = new Semaphore(1);
private Semaphore bar = new Semaphore(0);
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();
bar.release();
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
bar.acquire();
printBar.run();
foo.release();
}
}
}
|