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

 更新时间:2022年05月03日 11:57:22   作者:Jqcode  
本文主要介绍了Java让多线程按顺序执行的几种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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

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

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

public class ThreadJoinDemo {
    public static void main(String[] args) throws InterruptedException {
        final Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("打开冰箱!");
            }
        });
 
        final Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    thread1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("拿出一瓶牛奶!");
            }
        });
 
        final Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    thread2.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("关上冰箱!");
            }
        });
 
        //下面三行代码顺序可随意调整,程序运行结果不受影响,因为我们在子线程中通过“join()方法”已经指定了运行顺序。
        thread3.start();
        thread2.start();
        thread1.start();
 
    }
}

运行结果:

打开冰箱!
拿出一瓶牛奶!
关上冰箱!

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

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

public class ThreadMainJoinDemo {
    public static void main(String[] args) throws InterruptedException {
        final Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("打开冰箱!");
            }
        });
 
        final Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("拿出一瓶牛奶!");
            }
        });
 
        final Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("关上冰箱!");
            }
        });
 
        thread1.start();
        thread1.join();
        thread2.start();
        thread2.join();
        thread3.start();
    }
}

输出结果:

打开冰箱!
拿出一瓶牛奶!
关上冰箱!

通过倒数计时器CountDownLatch实现

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

public class ThreadCountDownLatchDemo {
 
    private static CountDownLatch countDownLatch1 = new CountDownLatch(1);
 
    private static CountDownLatch countDownLatch2 = new CountDownLatch(1);
 
    public static void main(String[] args) {
        final Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("打开冰箱!");
                countDownLatch1.countDown();
            }
        });
 
        final Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    countDownLatch1.await();
                    System.out.println("拿出一瓶牛奶!");
                    countDownLatch2.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
 
        final Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    countDownLatch2.await();
                    System.out.println("关上冰箱!");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
 
        //下面三行代码顺序可随意调整,程序运行结果不受影响
        thread3.start();
        thread1.start();
        thread2.start();
    }
}

输出结果:

打开冰箱!
拿出一瓶牛奶!
关上冰箱!

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

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

public class ThreadPoolDemo {
 
   static ExecutorService executorService = Executors.newSingleThreadExecutor();
 
    public static void main(String[] args) {
        final Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("打开冰箱!");
            }
        });
 
        final Thread thread2 =new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("拿出一瓶牛奶!");
            }
        });
 
        final Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("关上冰箱!");
            }
        });
        executorService.submit(thread1);
        executorService.submit(thread2);
        executorService.submit(thread3);
        executorService.shutdown();        //使用完毕记得关闭线程池
    }
 
}

输出结果:

打开冰箱!
拿出一瓶牛奶!
关上冰箱!

到此这篇关于Java让多线程按顺序执行的几种方法的文章就介绍到这了,更多相关Java多线程按顺序执行内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java定时/延时任务之Timer用法详解

    Java定时/延时任务之Timer用法详解

    在 Java Development Kit (JDK) 中,java.util.Timer 是一个用于调度任务的工具类,本文主要来和大家聊聊Timer的用法,有需要的小伙伴可以了解下
    2024-12-12
  • Mybatis+Druid+MybatisPlus多数据源配置方法

    Mybatis+Druid+MybatisPlus多数据源配置方法

    在项目开发中,经常需要连接多个数据库,使用Mybatis、Druid和MybatisPlus可以实现多数据源配置,通过定义配置类和修改配置文件,如properties或yaml,可以设置多个数据源,本文介绍了配置项包括Druid基本配置、数据源一、数据源二,感兴趣的朋友一起看看吧
    2024-09-09
  • Java调用groovy脚本的方式分享

    Java调用groovy脚本的方式分享

    Groovy 是一种基于 JVM 的动态语言,与 Java 语言紧密集成,可以很方便地在 Java 项目中使用。本文为大家整理了Java调用groovy脚本的几种方式,希望对大家有所帮助
    2023-04-04
  • Java语言Lang包下常用的工具类介绍

    Java语言Lang包下常用的工具类介绍

    这篇文章主要介绍了Java语言Lang包下常用的工具类介绍,次奥变觉得挺不错的,这里分享给大家,需要的朋友可以参考下。
    2017-10-10
  • Java中的AQS同步队列问题详解

    Java中的AQS同步队列问题详解

    AQS 提供一套基础的机制来实现线程的同步、阻塞与唤醒、等待队列等功能,也就是想要深入学习线程工具类,这个同步队列就必须得掌握,这篇文章主要介绍了Java中的AQS同步队列问题,需要的朋友可以参考下
    2022-06-06
  • SpringCloud中的Eureka注册中心详细解读

    SpringCloud中的Eureka注册中心详细解读

    这篇文章主要介绍了SpringCloud中的Eureka注册中心详细解读,想要参与服务注册发现的实例首先需要向Eureka服务器注册信息,注册在第一次心跳发生时提交,需要的朋友可以参考下
    2023-11-11
  • Spring Boot整合邮箱发送邮件实例

    Spring Boot整合邮箱发送邮件实例

    大家好,本篇文章主要讲的是Spring Boot整合邮箱发送邮件实例,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • Java中String、StringBuffer、StringBuilder的区别详解

    Java中String、StringBuffer、StringBuilder的区别详解

    java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间有什么区别呢?下面小编给大家总结了Java中String、StringBuffer、StringBuilder的区别详解,需要的朋友参考下吧
    2016-06-06
  • 深入了解Java方法的重载与重写

    深入了解Java方法的重载与重写

    在最初学习java的时候,人们都知道,java这种面向对象的语言,一共有三大特征,分别是:封装、继承、多态。多态的实现途径有三种:重写、重载、接口实现。本文就来为大家详细讲讲Java方法的重载与重写
    2022-07-07
  • Java程序去调用并执行shell脚本及问题总结(推荐)

    Java程序去调用并执行shell脚本及问题总结(推荐)

    这篇文章主要介绍了Java程序去调用并执行shell脚本及问题总结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06

最新评论