Java 多线程

目录

  • 在子线程中通过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)的优点,串行执行所有任务。 ```java public class ThreadPoolDemo {

    static ExecutorService executorService = Executors.newSingleThreadExecutor();

    public static void main(String[] args) {

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

    }

}

  1. 输出结果:
  2. ```java
  3. 打开冰箱!
  4. 拿出一瓶牛奶!
  5. 关上冰箱!