Leetcode 1115.交替打印FooBar

  1. public class FooBar {
  2. private int n;
  3. private volatile boolean flag;
  4. public FooBar(int n) {
  5. this.n = n;
  6. }
  7. public static void main(String[] args) {
  8. FooBar main=new FooBar(10);
  9. //用匿名内部类创建一个线程打印foo
  10. new Thread(()->{
  11. try {
  12. main.foo(()->System.out.println("foo"));
  13. } catch (InterruptedException e) {
  14. // TODO Auto-generated catch block
  15. e.printStackTrace();
  16. }
  17. }).start();
  18. //用匿名内部类创建一个线程打印bar
  19. new Thread(()->{
  20. try {
  21. main.bar(()->System.out.println("bar"));
  22. } catch (InterruptedException e) {
  23. // TODO Auto-generated catch block
  24. e.printStackTrace();
  25. }
  26. }).start();
  27. }
  28. //手太阴肺经 BLOCKING Queue
  29. private BlockingQueue<Integer> bar = new ArrayBlockingQueue<>(1);
  30. private BlockingQueue<Integer> foo = new ArrayBlockingQueue<>(1);
  31. public void foo(Runnable printFoo) throws InterruptedException {
  32. for (int i = 0; i < n; i++) {
  33. foo.put(i);
  34. printFoo.run();
  35. bar.put(i);
  36. }
  37. }
  38. public void bar(Runnable printBar) throws InterruptedException {
  39. for (int i = 0; i < n; i++) {
  40. bar.take();
  41. printBar.run();
  42. foo.take();
  43. }
  44. }
  45. //手阳明大肠经CyclicBarrier 控制先后
  46. class FooBar6 {
  47. private int n;
  48. public FooBar6(int n) {
  49. this.n = n;
  50. }
  51. CyclicBarrier cb = new CyclicBarrier(2);
  52. volatile boolean fin = true;
  53. public void foo(Runnable printFoo) throws InterruptedException {
  54. for (int i = 0; i < n; i++) {
  55. while(!fin);
  56. printFoo.run();
  57. fin = false;
  58. try {
  59. cb.await();
  60. } catch (BrokenBarrierException e) {}
  61. }
  62. }
  63. public void bar(Runnable printBar) throws InterruptedException {
  64. for (int i = 0; i < n; i++) {
  65. try {
  66. cb.await();
  67. } catch (BrokenBarrierException e) {}
  68. printBar.run();
  69. fin = true;
  70. }
  71. }
  72. }
  73. //手少阴心经 自旋 + 让出CPU
  74. class FooBar5 {
  75. private int n;
  76. public FooBar5(int n) {
  77. this.n = n;
  78. }
  79. volatile boolean permitFoo = true;
  80. public void foo(Runnable printFoo) throws InterruptedException {
  81. for (int i = 0; i < n; ) {
  82. if(permitFoo) {
  83. printFoo.run();
  84. i++;
  85. permitFoo = false;
  86. }else{
  87. Thread.yield();
  88. }
  89. }
  90. }
  91. public void bar(Runnable printBar) throws InterruptedException {
  92. for (int i = 0; i < n; ) {
  93. if(!permitFoo) {
  94. printBar.run();
  95. i++;
  96. permitFoo = true;
  97. }else{
  98. Thread.yield();
  99. }
  100. }
  101. }
  102. }
  103. //手少阳三焦经 可重入锁 + Condition
  104. class FooBar4 {
  105. private int n;
  106. public FooBar4(int n) {
  107. this.n = n;
  108. }
  109. Lock lock = new ReentrantLock(true);
  110. private final Condition foo = lock.newCondition();
  111. volatile boolean flag = true;
  112. public void foo(Runnable printFoo) throws InterruptedException {
  113. for (int i = 0; i < n; i++) {
  114. lock.lock();
  115. try {
  116. while(!flag) {
  117. foo.await();
  118. }
  119. printFoo.run();
  120. flag = false;
  121. foo.signal();
  122. }finally {
  123. lock.unlock();
  124. }
  125. }
  126. }
  127. public void bar(Runnable printBar) throws InterruptedException {
  128. for (int i = 0; i < n;i++) {
  129. lock.lock();
  130. try {
  131. while(flag) {
  132. foo.await();
  133. }
  134. printBar.run();
  135. flag = true;
  136. foo.signal();
  137. }finally {
  138. lock.unlock();
  139. }
  140. }
  141. }
  142. }
  143. //手厥阴心包经 synchronized + 标志位 + 唤醒
  144. class FooBar3 {
  145. private int n;
  146. // 标志位,控制执行顺序,true执行printFoo,false执行printBar
  147. private volatile boolean type = true;
  148. private final Object foo= new Object(); // 锁标志
  149. public FooBar3(int n) {
  150. this.n = n;
  151. }
  152. public void foo(Runnable printFoo) throws InterruptedException {
  153. for (int i = 0; i < n; i++) {
  154. synchronized (foo) {
  155. while(!type){
  156. foo.wait();
  157. }
  158. printFoo.run();
  159. type = false;
  160. foo.notifyAll();
  161. }
  162. }
  163. }
  164. public void bar(Runnable printBar) throws InterruptedException {
  165. for (int i = 0; i < n; i++) {
  166. synchronized (foo) {
  167. while(type){
  168. foo.wait();
  169. }
  170. printBar.run();
  171. type = true;
  172. foo.notifyAll();
  173. }
  174. }
  175. }
  176. }
  177. //手太阳小肠经 信号量 适合控制顺序
  178. class FooBar2 {
  179. private int n;
  180. private Semaphore foo = new Semaphore(1);
  181. private Semaphore bar = new Semaphore(0);
  182. public FooBar2(int n) {
  183. this.n = n;
  184. }
  185. public void foo(Runnable printFoo) throws InterruptedException {
  186. for (int i = 0; i < n; i++) {
  187. foo.acquire();
  188. printFoo.run();
  189. bar.release();
  190. }
  191. }
  192. public void bar(Runnable printBar) throws InterruptedException {
  193. for (int i = 0; i < n; i++) {
  194. bar.acquire();
  195. printBar.run();
  196. foo.release();
  197. }
  198. }
  199. }
  200. }