https://leetcode.cn/problems/print-foobar-alternately/solution/duo-xian-cheng-liu-mai-shen-jian-ni-xue-d220n/

顺序十次打印foo和Bar

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