当前位置:   article > 正文

让多线程按顺序执行的几种方法_c++多线程顺序执行

c++多线程顺序执行

文章介绍4种方法,简单易懂,通过4个demo抛砖引玉。

目录

在子线程中通过join()方法指定顺序

在主线程中通过join()方法指定顺序

通过倒数计时器CountDownLatch实现

通过创建单一化线程池newSingleThreadExecutor()实现


在子线程中通过join()方法指定顺序

通过join()方法使当前线程“阻塞”,等待指定线程执行完毕后继续执行。举例:在线程thread2中,加上一句thread1.join(),其意义在于,当前线程2运行到此行代码时会进入阻塞状态,直到线程thread1执行完毕后,线程thread2才会继续运行,这就保证了线程thread1与线程thread2的运行顺序。

  1. public class ThreadJoinDemo {
  2. public static void main(String[] args) throws InterruptedException {
  3. final Thread thread1 = new Thread(new Runnable() {
  4. @Override
  5. public void run() {
  6. System.out.println("打开冰箱!");
  7. }
  8. });
  9. final Thread thread2 = new Thread(new Runnable() {
  10. @Override
  11. public void run() {
  12. try {
  13. thread1.join();
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. }
  17. System.out.println("拿出一瓶牛奶!");
  18. }
  19. });
  20. final Thread thread3 = new Thread(new Runnable() {
  21. @Override
  22. public void run() {
  23. try {
  24. thread2.join();
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. System.out.println("关上冰箱!");
  29. }
  30. });
  31. //下面三行代码顺序可随意调整,程序运行结果不受影响,因为我们在子线程中通过“join()方法”已经指定了运行顺序。
  32. thread3.start();
  33. thread2.start();
  34. thread1.start();
  35. }
  36. }

运行结果:

  1. 打开冰箱!
  2. 拿出一瓶牛奶!
  3. 关上冰箱!

在主线程中通过join()方法指定顺序

简单说一下子线程与主线程的区别,子线程指的是发生在Thread内部的代码,主线程指的是发生在main函数中的代码,我们可以在main函数中通过join()方法让主线程阻塞等待以达到指定顺序执行的目的。

  1. public class ThreadMainJoinDemo {
  2. public static void main(String[] args) throws InterruptedException {
  3. final Thread thread1 = new Thread(new Runnable() {
  4. @Override
  5. public void run() {
  6. System.out.println("打开冰箱!");
  7. }
  8. });
  9. final Thread thread2 = new Thread(new Runnable() {
  10. @Override
  11. public void run() {
  12. System.out.println("拿出一瓶牛奶!");
  13. }
  14. });
  15. final Thread thread3 = new Thread(new Runnable() {
  16. @Override
  17. public void run() {
  18. System.out.println("关上冰箱!");
  19. }
  20. });
  21. thread1.start();
  22. thread1.join();
  23. thread2.start();
  24. thread2.join();
  25. thread3.start();
  26. }
  27. }

输出结果:

  1. 打开冰箱!
  2. 拿出一瓶牛奶!
  3. 关上冰箱!

通过倒数计时器CountDownLatch实现

CountDownLatch通过计数器提供了更灵活的控制,只要检测到计数器为0当前线程就可以往下执行而不用管相应的thread是否执行完毕。

  1. public class ThreadCountDownLatchDemo {
  2. private static CountDownLatch countDownLatch1 = new CountDownLatch(1);
  3. private static CountDownLatch countDownLatch2 = new CountDownLatch(1);
  4. public static void main(String[] args) {
  5. final Thread thread1 = new Thread(new Runnable() {
  6. @Override
  7. public void run() {
  8. System.out.println("打开冰箱!");
  9. countDownLatch1.countDown();
  10. }
  11. });
  12. final Thread thread2 = new Thread(new Runnable() {
  13. @Override
  14. public void run() {
  15. try {
  16. countDownLatch1.await();
  17. System.out.println("拿出一瓶牛奶!");
  18. countDownLatch2.countDown();
  19. } catch (InterruptedException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. });
  24. final Thread thread3 = new Thread(new Runnable() {
  25. @Override
  26. public void run() {
  27. try {
  28. countDownLatch2.await();
  29. System.out.println("关上冰箱!");
  30. } catch (InterruptedException e) {
  31. e.printStackTrace();
  32. }
  33. }
  34. });
  35. //下面三行代码顺序可随意调整,程序运行结果不受影响
  36. thread3.start();
  37. thread1.start();
  38. thread2.start();
  39. }
  40. }

输出结果:

  1. 打开冰箱!
  2. 拿出一瓶牛奶!
  3. 关上冰箱!

通过创建单一化线程池newSingleThreadExecutor()实现

单线程化线程池(newSingleThreadExecutor)的优点,串行执行所有任务。

  1. public class ThreadPoolDemo {
  2. static ExecutorService executorService = Executors.newSingleThreadExecutor();
  3. public static void main(String[] args) {
  4. final Thread thread1 = new Thread(new Runnable() {
  5. @Override
  6. public void run() {
  7. System.out.println("打开冰箱!");
  8. }
  9. });
  10. final Thread thread2 =new Thread(new Runnable() {
  11. @Override
  12. public void run() {
  13. System.out.println("拿出一瓶牛奶!");
  14. }
  15. });
  16. final Thread thread3 = new Thread(new Runnable() {
  17. @Override
  18. public void run() {
  19. System.out.println("关上冰箱!");
  20. }
  21. });
  22. executorService.submit(thread1);
  23. executorService.submit(thread2);
  24. executorService.submit(thread3);
  25. executorService.shutdown(); //使用完毕记得关闭线程池
  26. }
  27. }

输出结果:

  1. 打开冰箱!
  2. 拿出一瓶牛奶!
  3. 关上冰箱!

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/197823
推荐阅读
相关标签
  

闽ICP备14008679号