LeetCode 1115:交替打印FooBar
题目描述
给你一个类:
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 实例:
- 线程 A 将会调用 foo() 方法,而
- 线程 B 将会调用 bar() 方法
请设计修改程序,以确保 “foobar” 被输出 n 次。
解题思路
参考leetcode 1195 与 1114,思路是相通的:
LeetCode 1195:交替打印字符串
LeetCode 1114:按序打印
代码实现
Semaphore
class FooBar {
private int n;
private Semaphore s1 = new Semaphore(1);
private Semaphore s2 = new Semaphore(0);
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
s1.acquire();
printFoo.run();
s2.release();
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
s2.acquire();
printBar.run();
s1.release();
}
}
}
CyclicBarrier
class FooBar {
private int n;
private CyclicBarrier cb = new CyclicBarrier(2);
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for(int i = 1;i <= 2*n ; i++){
if(i % 2 == 1){
printFoo.run();
}
try{
cb.await();
}catch(Exception e){
e.printStackTrace();
}
}
}
public void bar(Runnable printBar) throws InterruptedException {
for(int i = 1;i <= 2*n ; i++){
if(i % 2 == 0){
printBar.run();
}
try{
cb.await();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
ReentrantLock + Condition
class FooBar {
private int n;
private volatile int i = 1;
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
while(i <= 2*n){
lock.lock();
try{
if(i <= 2*n && i % 2 == 1){
printFoo.run();
condition.signalAll();
i++;
}else{
condition.await();
}
}finally{
lock.unlock();
}
}
}
public void bar(Runnable printBar) throws InterruptedException {
while(i <= 2*n){
lock.lock();
try{
if(i <= 2*n && i % 2 == 0){
printBar.run();
condition.signalAll();
i++;
}else{
condition.await();
}
}finally{
lock.unlock();
}
}
}
}
总结
本题来源于Leetcode中 归属于多线程类型题目。
同许多在算法道路上不断前行的人一样,不断练习,修炼自己!
如有博客中存在的疑问或者建议,可以在下方留言一起交流,感谢各位!
觉得本博客有用的客官,可以给个赞鼓励下! 嘿嘿