使用多线程交替打印123123123…

方法一:使用Lock lock = new ReentrantLock();

  1. `lock.lock();`
  2. `lock.unlock();`
  1. package junhaox.cn.interview;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.PrintStream;
  5. import java.io.PrintWriter;
  6. import java.util.concurrent.locks.Condition;
  7. import java.util.concurrent.locks.Lock;
  8. import java.util.concurrent.locks.ReentrantLock;
  9. /**
  10. * 多线程交替打印123123123...
  11. * 方法1
  12. * @author wjh
  13. *
  14. */
  15. public class LoopPrint {
  16. // 从1 开始打印
  17. int num = 1;
  18. Lock lock = new ReentrantLock();
  19. // 三个线程的通知
  20. Condition condition1 = lock.newCondition();
  21. Condition condition2 = lock.newCondition();
  22. Condition condition3 = lock.newCondition();
  23. public void print1() {
  24. // 加锁防止多个线程同时操作num
  25. lock.lock();
  26. try {
  27. if (num != 1) {
  28. condition1.await();
  29. }
  30. System.out.println(Thread.currentThread().getName()+num);
  31. // Thread.sleep(1000);
  32. // 通知线程2
  33. num = 2;
  34. condition2.signal();
  35. } catch (InterruptedException e) {
  36. e.printStackTrace();
  37. }finally {
  38. // 使用完毕记得释放锁
  39. lock.unlock();
  40. }
  41. }
  42. public void print2() {
  43. // 加锁防止多个线程同时操作num
  44. lock.lock();
  45. try {
  46. if (num != 2) {
  47. condition2.await();
  48. }
  49. System.out.println(Thread.currentThread().getName()+num);
  50. // Thread.sleep(1000);
  51. // 通知线程3
  52. num = 3;
  53. condition3.signal();
  54. } catch (InterruptedException e) {
  55. e.printStackTrace();
  56. }finally {
  57. lock.unlock();
  58. }
  59. }
  60. public void print3() {
  61. // 加锁防止多个线程同时操作num
  62. lock.lock();
  63. try {
  64. if (num != 3) {
  65. condition3.await();
  66. }
  67. System.out.println(Thread.currentThread().getName()+num);
  68. // Thread.sleep(1000);
  69. // 通知线程1
  70. num = 1;
  71. condition1.signal();
  72. } catch (InterruptedException e) {
  73. e.printStackTrace();
  74. }finally {
  75. lock.unlock();
  76. }
  77. }
  78. public static void main(String[] args) {
  79. LoopPrint print = new LoopPrint();
  80. // System.out.println(111);
  81. new Thread(()->{
  82. while (true) {
  83. print.print1();
  84. }
  85. }).start();
  86. new Thread(()->{
  87. while (true) {
  88. print.print2();
  89. }
  90. }).start();
  91. new Thread(()->{
  92. while (true) {
  93. print.print3();
  94. }
  95. }).start();
  96. }
  97. }

方法二:使用synchronized wait()notify()

  1. package junhaox.cn.interview;
  2. import java.io.FileNotFoundException;
  3. import java.io.PrintStream;
  4. /**
  5. * 多线程交替打印123123123...
  6. * 方法1
  7. * @author wjh
  8. *
  9. */
  10. public class SnyLoopPrint {
  11. int num = 1;
  12. synchronized public void print1() {
  13. try {
  14. if (num != 1) {
  15. System.out.println("线程1进入等待");
  16. this.wait();
  17. }else {
  18. System.out.println(Thread.currentThread().getName()+num);
  19. // Thread.sleep(1000);
  20. // 通知线程2
  21. num = 2;
  22. this.notifyAll();
  23. }
  24. } catch (InterruptedException e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. synchronized public void print2() {
  29. try {
  30. if (num != 2) {
  31. System.out.println("线程2进入等待");
  32. this.wait();
  33. }else {
  34. System.out.println(Thread.currentThread().getName()+num);
  35. // Thread.sleep(1000);
  36. // 通知线程3
  37. num = 3;
  38. this.notifyAll();
  39. }
  40. } catch (InterruptedException e) {
  41. e.printStackTrace();
  42. }
  43. }
  44. synchronized public void print3() {
  45. try {
  46. if (num != 3) {
  47. System.out.println("线程3进入等待");
  48. this.wait();
  49. }else {
  50. System.out.println(Thread.currentThread().getName()+num);
  51. // Thread.sleep(1000);
  52. // 通知线程1
  53. num = 1;
  54. this.notifyAll();
  55. }
  56. } catch (InterruptedException e) {
  57. e.printStackTrace();
  58. }
  59. }
  60. public static void main(String[] args) {
  61. SnyLoopPrint print = new SnyLoopPrint(1);
  62. // System.out.println(111);
  63. new Thread(()->{
  64. while (true) {
  65. print.print1();
  66. }
  67. }).start();
  68. new Thread(()->{
  69. while (true) {
  70. print.print2();
  71. }
  72. }).start();
  73. new Thread(()->{
  74. while (true) {
  75. print.print3();
  76. }
  77. }).start();
  78. }
  79. }

注意:使用方法一和二时一定是先修改num的值在进行通知

方法三:使用信号量的方式Semaphore sm1 = new Semaphore(1);

  1. package junhaox.cn.interview;
  2. import java.util.concurrent.Semaphore;
  3. public class SemaphoreDemo {
  4. //
  5. Semaphore sm1 = new Semaphore(1);
  6. Semaphore sm2 = new Semaphore(0);
  7. Semaphore sm3 = new Semaphore(0);
  8. private void print(int value, Semaphore current, Semaphore next) {
  9. try {
  10. // 获取管道(总共只有1个),用完就停
  11. current.acquire(1);
  12. System.out.println(Thread.currentThread().getName()+"----"+value);
  13. Thread.sleep(1000);
  14. // 释放一个管道,谁释放谁拿
  15. next.release(1);
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. public void print1() {
  21. print(1, sm1, sm2);
  22. }
  23. public void print2() {
  24. print(2, sm2, sm3);
  25. }
  26. public void print3() {
  27. print(3, sm3, sm1);
  28. }
  29. public static void main(String[] args) {
  30. SemaphoreDemo sd = new SemaphoreDemo();
  31. new Thread(()->{
  32. while (true) {
  33. sd.print1();
  34. }
  35. }).start();
  36. new Thread(()->{
  37. while (true) {
  38. sd.print2();
  39. }
  40. }).start();
  41. new Thread(()->{
  42. while (true) {
  43. sd.print3();
  44. }
  45. }).start();
  46. }
  47. }