• 多线程顺序运行的 4 种方法,面试随便问!


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

    1、在子线程中通过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();
     
        }
    }
    

    运行结果:

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

    2、在主线程中通过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();
        }
    }
    

    基础就不介绍了,多线程系列我博客教程写了很多了,这里推荐大家看看吧:https://www.javastack.cn/categories/Java/

    输出结果:

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

    3、通过倒数计时器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();
        }
    }
    

    输出结果:

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

    4、通过创建单一化线程池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();        //使用完毕记得关闭线程池
        }
     
    }
    

    输出结果:

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

    来源:blog.csdn.net/jqc874789596/article/details/100557300

    近期热文推荐:

    1.1,000+ 道 Java面试题及答案整理(2022最新版)

    2.劲爆!Java 协程要来了。。。

    3.Spring Boot 2.x 教程,太全了!

    4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!

    5.《Java开发手册(嵩山版)》最新发布,速速下载!

    觉得不错,别忘了随手点赞+转发哦!

  • 相关阅读:
    CentOS 下实现两台服务器之间的共享NFS
    CentOS 下安装无线哥的老爷机DELL的无线驱动
    PHP 如何读取一个1G的文件大小
    php 经典的算法题你懂的
    mongodb与mysql命令对比
    TCP协议的三次握手和四次挥手过程
    java 发送带Basic Auth认证的http post请求实例代码
    HTTP基本认证(Basic Authentication)的JAVA实例代码
    Http协议
    MySQL主从同步那点事儿
  • 原文地址:https://www.cnblogs.com/javastack/p/16531021.html
Copyright © 2020-2023  润新知