★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
Suppose you are given the following code:java
class FooBar {
public void foo() {
for (int i = 0; i < n; i++) {
print("foo");
}
}git
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.github
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.async
咱們提供一個類:ui
class FooBar {
public void foo() {
for (int i = 0; i < n; i++) {
print("foo");
}
}this
public void bar() {
for (int i = 0; i < n; i++) {
print("bar");
}
}
}
兩個不一樣的線程將會共用一個 FooBar 實例。其中一個線程將會調用 foo() 方法,另外一個線程將會調用 bar() 方法。spa
請設計修改程序,以確保 "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 }