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,思路是相通的:
代码实现
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(); } } } }
总结
觉得本博客有用的客官,可以给个赞鼓励下! 嘿嘿
上一篇:
通过多线程提高代码的执行效率例子
下一篇:
读刘未鹏《暗时间》有感