[Java]LeetCode1115. 交替打印FooBar | Print FooBar Alternately
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
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.
我们提供一个类:
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" 将被输出两次。
15ms
1 import java.util.concurrent.locks.Condition; 2 import java.util.concurrent.locks.Lock; 3 import java.util.concurrent.locks.ReentrantLock; 4 5 class FooBar { 6 private int n; 7 private boolean fooFlag; 8 private boolean barFlag; 9 private Lock lock; 10 private Condition fooCondition; 11 private Condition barCondition; 12 13 public FooBar(int n) { 14 this.n = n; 15 this.fooFlag = false; 16 this.barFlag = true; 17 this.lock = new ReentrantLock(); 18 this.fooCondition = lock.newCondition(); 19 this.barCondition = lock.newCondition(); 20 } 21 22 public void foo(Runnable printFoo) throws InterruptedException { 23 for (int i = 0; i < n; i++) { 24 lock.lock(); 25 26 try { 27 while (fooFlag) { 28 fooCondition.await(); 29 } 30 31 /** 32 * printFoo.run() outputs "foo". Do not change or remove this line. 33 */ 34 printFoo.run(); 35 fooFlag = true; 36 barFlag = false; 37 barCondition.signal(); 38 } finally { 39 lock.unlock(); 40 } 41 } 42 } 43 44 public void bar(Runnable printBar) throws InterruptedException { 45 for (int i = 0; i < n; i++) { 46 lock.lock(); 47 48 try { 49 while (barFlag) { 50 barCondition.await(); 51 } 52 53 /** 54 * printBar.run() outputs "bar". Do not change or remove this line. 55 */ 56 printBar.run(); 57 barFlag = true; 58 fooFlag = false; 59 fooCondition.signal(); 60 } finally { 61 lock.unlock(); 62 } 63 } 64 } 65 }
16ms
1 import java.util.concurrent.Semaphore; 2 3 class FooBar { 4 private int n; 5 private Semaphore semaphore = new Semaphore(1); 6 private Semaphore semaphore2 = new Semaphore(0); 7 public FooBar(int n) { 8 this.n = n; 9 } 10 11 public void foo(Runnable printFoo) throws InterruptedException { 12 13 for (int i = 0; i < n; i++) { 14 semaphore.acquire(); 15 // printFoo.run() outputs "foo". Do not change or remove this line. 16 printFoo.run(); 17 semaphore2.release(); 18 } 19 } 20 21 public void bar(Runnable printBar) throws InterruptedException { 22 23 for (int i = 0; i < n; i++) { 24 semaphore2.acquire(); 25 // printBar.run() outputs "bar". Do not change or remove this line. 26 printBar.run(); 27 semaphore.release(); 28 } 29 } 30 }
24ms
1 class FooBar { 2 private int n; 3 private static final Object LOCK = new Object(); 4 public FooBar(int n) { 5 this.n = n; 6 } 7 8 public void foo(Runnable printFoo) throws InterruptedException { 9 for (int i = 0; i < n; i++) { 10 synchronized (LOCK) { 11 LOCK.notify(); 12 printFoo.run(); 13 LOCK.wait(); 14 } 15 } 16 } 17 18 public void bar(Runnable printBar) throws InterruptedException { 19 for (int i = 0; i < n; i++) { 20 synchronized (LOCK) { 21 LOCK.notify(); 22 printBar.run(); 23 if (i < n - 1) { 24 LOCK.wait(); 25 } 26 } 27 } 28 } 29 }