当前位置:   article > 正文

如何保证线程A,B,C顺序执行,或者C在A、B后执行?_线程abc按照顺序执行

线程abc按照顺序执行

第一种方案:使用CountDownLatch工具类

CountDownLatch:是Java多线程编程中的一个同步工具类(计数锁),它允许一个或多个线程等待其他线程完成操作后再继续执行。其内部维护了一个计数器,当线程在执行任务完成后调用countDown()方法,该方法会将计数器的值减一,而等待线程通过调用await()方法来等待计数器的值变为0后才执行。

设计实现

  1. //设计线程类
  2. public class ThreadA implements Runnable {
  3. //定时锁
  4. private CountDownLatch latch;
  5. //初始化
  6. public ThreadA(CountDownLatch latch){
  7. this.latch=latch;
  8. }
  9. @Override
  10. public void run() {
  11. //1.执行
  12. System.out.println("A线程执行");
  13. //2.计数减1
  14. latch.countDown();
  15. }
  16. }
  17. public class ThreadB implements Runnable {
  18. //两个定时锁(上一个线程和当前线程)
  19. private CountDownLatch latch1;
  20. private CountDownLatch latch2;
  21. //初始化
  22. public ThreadB(CountDownLatch latch1,CountDownLatch latch2){
  23. this.latch1=latch1;
  24. this.latch2=latch2;
  25. }
  26. @Override
  27. public void run() {
  28. try {
  29. //1.等待上一个线程执行完成
  30. latch1.await();
  31. //2.执行
  32. System.out.println("B线程执行");
  33. //3.计数减1
  34. latch2.countDown();
  35. } catch (InterruptedException e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. }
  40. public class ThreadC implements Runnable {
  41. //定时锁
  42. private CountDownLatch latch;
  43. //初始化
  44. public ThreadC(CountDownLatch latch){
  45. this.latch=latch;
  46. }
  47. @Override
  48. public void run() {
  49. try {
  50. //1.等待
  51. latch.await();
  52. //2.执行
  53. System.out.println("C线程执行");
  54. } catch (InterruptedException e) {
  55. e.printStackTrace();
  56. }
  57. }
  58. }
  59. //测试线程A、B、C顺序执行
  60. public class Main {
  61. public static void main(String[] args) {
  62. //创建线程A,B的定时锁,计数为1
  63. CountDownLatch latchA=new CountDownLatch(1);
  64. CountDownLatch latchB=new CountDownLatch(1);
  65. //创建线程A、B、C
  66. Thread a = new Thread(new ThreadA(latchA));
  67. Thread b = new Thread(new ThreadB(latchA,latchB));
  68. Thread c = new Thread(new ThreadC(latchB));
  69. //a,b,c顺序执行
  70. a.start();
  71. b.start();
  72. c.start();
  73. }
  74. }

第二种方案:使用Semaphore同步工具

Semaphore(信号量):是一种控制并发访问资源的同步工具,用来限制同时访问某个资源的线程数量。Semaphore内部维护一个计数器,该计数器用于表示可用的许可证数量。线程在访问资源之前必须先通过acquire()方法获得许可证,如果许可证数量为0,则线程必须等待,直到有其他线程释放许可证。当线程使用完资源后,使用release()方法释放许可证,以便其他线程可以继续访问资源。

(实现原理和上个方案思想相同)

第三种方案:使用wait()、notify()和notifyAll()方法

wait() 方法:使当前线程进入等待状态

notify() 方法:唤醒在相同对象上调用 wait() 方法进入等待状态的线程中的一个线程

notifyAll() 方法:唤醒在相同对象上调用 wait() 方法进入等待状态的所有线程只有一个线程会获得(抢到)对象锁,其余线程将继续等待锁的释放)。

  1. class Main {
  2. static Object lock = new Object();//对象锁
  3. static int threadId = 1;//当前执行线程标志
  4. public static void main(String[] args) {
  5. //线程A、B、C的标志分别为1,2,3
  6. //创建三个线程
  7. Thread a = new Thread(new Runnable() {
  8. @Override
  9. public void run() {
  10. try {
  11. //获取对象锁
  12. synchronized (lock) {
  13. //没有到当前线程执行,则释放锁进入等待状态
  14. while (threadId != 1) {
  15. lock.wait();
  16. }
  17. //轮到当前线程执行
  18. System.out.println("线程A执行");
  19. threadId = 2;
  20. lock.notifyAll();
  21. }
  22. } catch (InterruptedException e) {
  23. e.printStackTrace();
  24. }
  25. }
  26. });
  27. Thread b = new Thread(new Runnable() {
  28. @Override
  29. public void run() {
  30. try {
  31. synchronized (lock) {
  32. while (threadId != 2) {
  33. lock.wait();
  34. }
  35. System.out.println("线程B执行");
  36. threadId = 3;
  37. lock.notifyAll();
  38. }
  39. } catch (InterruptedException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. });
  44. Thread c = new Thread(new Runnable() {
  45. @Override
  46. public void run() {
  47. try {
  48. synchronized (lock) {
  49. while (threadId != 3) {
  50. lock.wait();
  51. }
  52. System.out.println("线程C执行");
  53. threadId = 1;
  54. lock.notifyAll();
  55. }
  56. } catch (InterruptedException e) {
  57. e.printStackTrace();
  58. }
  59. }
  60. });
  61. // 线程顺序执行
  62. a.start();
  63. b.start();
  64. c.start();
  65. }
  66. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/197804
推荐阅读
相关标签
  

闽ICP备14008679号