1. package cn.itcast.pattern;
    2. import java.util.Arrays;
    3. import java.util.concurrent.locks.Condition;
    4. import java.util.concurrent.locks.LockSupport;
    5. import java.util.concurrent.locks.ReentrantLock;
    6. class SyncWaitNotify {
    7. private int flag;
    8. private int loopNumber;
    9. public SyncWaitNotify(int flag, int loopNumber) {
    10. this.flag = flag;
    11. this.loopNumber = loopNumber;
    12. }
    13. public void print(int waitFlag, int nextFlag, String str) {
    14. for (int i = 0; i < loopNumber; i++) {
    15. synchronized (this) {
    16. while (this.flag != waitFlag) {
    17. try {
    18. this.wait();
    19. } catch (InterruptedException e) {
    20. e.printStackTrace();
    21. }
    22. }
    23. System.out.print(str);
    24. flag = nextFlag;
    25. this.notifyAll();
    26. }
    27. }
    28. }
    29. }
    30. class SyncLock extends ReentrantLock {
    31. Condition waitSet = this.newCondition();
    32. private int flag;
    33. private int loopNumber;
    34. public SyncLock(int flag, int loopNumber) {
    35. this.flag = flag;
    36. this.loopNumber = loopNumber;
    37. }
    38. public void print(int waitFlag, int nextFlag, String str) {
    39. for (int i = 0; i < loopNumber; i++) {
    40. this.lock();
    41. try {
    42. while (this.flag != waitFlag) {
    43. try {
    44. waitSet.await();
    45. } catch (InterruptedException e) {
    46. e.printStackTrace();
    47. }
    48. }
    49. System.out.print(str);
    50. this.flag = nextFlag;
    51. waitSet.signalAll();
    52. } finally {
    53. this.unlock();
    54. }
    55. }
    56. }
    57. }
    58. class SyncPark {
    59. private int loopNumber;
    60. private Thread[] threads;
    61. public SyncPark(int loopNumber) {
    62. this.loopNumber = loopNumber;
    63. }
    64. public void setThreads(Thread... threads) {
    65. this.threads = threads;
    66. }
    67. public void print(String str) {
    68. for (int i = 0; i < loopNumber; i++) {
    69. LockSupport.park();
    70. System.out.print(str);
    71. LockSupport.unpark(nextThread());
    72. }
    73. }
    74. private Thread nextThread() {
    75. Thread current = Thread.currentThread();
    76. int index = 0;
    77. for (int i = 0; i < threads.length; i++) {
    78. if(threads[i] == current) {
    79. index = i;
    80. break;
    81. }
    82. }
    83. if(index < threads.length - 1) {
    84. return threads[index+1];
    85. } else {
    86. return threads[0];
    87. }
    88. }
    89. public void start() {
    90. for (Thread thread : threads) {
    91. thread.start();
    92. }
    93. LockSupport.unpark(threads[0]);
    94. }
    95. }
    96. public class TestOrder {
    97. public static void main(String[] args) {
    98. test3();
    99. }
    100. private static void test3() {
    101. SyncPark syncPark = new SyncPark(3);
    102. Thread t1 = new Thread(() -> {
    103. syncPark.print("a");
    104. });
    105. Thread t2 = new Thread(() -> {
    106. syncPark.print("b");
    107. });
    108. Thread t3 = new Thread(() -> {
    109. syncPark.print("c\n");
    110. });
    111. syncPark.setThreads(t1, t2, t3);
    112. syncPark.start();
    113. }
    114. private static void test2() {
    115. SyncLock syncLock = new SyncLock(1, 5);
    116. new Thread(() -> {
    117. syncLock.print(1, 2, "a");
    118. }).start();
    119. new Thread(() -> {
    120. syncLock.print(2, 3, "b");
    121. }).start();
    122. new Thread(() -> {
    123. syncLock.print(3, 1, "c\n");
    124. }).start();
    125. }
    126. private static void test1() {
    127. SyncWaitNotify syncWaitNotify = new SyncWaitNotify(1, 5);
    128. new Thread(() -> {
    129. syncWaitNotify.print(1, 2, "a");
    130. }).start();
    131. new Thread(() -> {
    132. syncWaitNotify.print(2, 3, "b");
    133. }).start();
    134. new Thread(() -> {
    135. syncWaitNotify.print(3, 1, "c\n");
    136. }).start();
    137. }
    138. }