• 线程如何按照自己指定的顺序执行


    如下代码所示,我们按照顺序写了一段多线程的代码,然后想让t1,t2,t3都能顺序的执行

    /**
         * 没有顺序执行的示例
         */
        public static void test() {
            Thread t1 = new Thread(() -> {
                System.out.println("1");
            }, "t1");
    
            Thread t2 = new Thread(() -> {
                System.out.println("2");
            }, "t2");
    
            Thread t3 = new Thread(() -> {
                System.out.println("3");
            }, "t3");
    
            t1.start();
            t2.start();
            t3.start();
        }

    但是运行后,它并不是按照顺序执行的,如下:

    1

    3

    2

    如何才能保证顺序执行呢?

    方法一:

    使用Join

    jion的意思是加入线程,需要等待线程执行完毕以后,其它线程才能够继续执行

    代码演示:

    public static void test2() throws InterruptedException {
            Thread t1 = new Thread(() -> {
                System.out.println("1");
            }, "t1");
    
            Thread t2 = new Thread(() -> {
                System.out.println("2");
            }, "t2");
    
            Thread t3 = new Thread(() -> {
                System.out.println("3");
            }, "t3");
    
            t1.start();
            t1.join();
    
            t2.start();
            t2.join();
    
            t3.start();
            t3.join();
        }

    运行结果:

    1

    2

    3

    主要利用了join的阻塞效果(阻塞主线程),来达到我们的使用目的。

    方式二:利用Executors线程池

    Executors是JUC里面的操作类,可以方便的给我们提供线程池的操作,这里我们使用Executors中的newSingleThreadExecutor方法,创建一个单线程的线程池。

     /**
         * 使用线程池
         */
        public static void test3() {
            // 创建一个单例线程
            ExecutorService executorService = Executors.newSingleThreadExecutor();
            Thread t1 = new Thread(() -> {
                System.out.println("1");
            }, "t1");
    
            Thread t2 = new Thread(() -> {
                System.out.println("2");
            }, "t2");
    
            Thread t3 = new Thread(() -> {
                System.out.println("3");
            }, "t3");
            executorService.submit(t1);
            executorService.submit(t2);
            executorService.submit(t3);
        }
    

    运行结果:

    1

    2

    3

    这里主要就是利用了newSingleThreadExecutor()方法,其实原理很简单,因为单例线程池的内部是一个基于FIFO的队列,也就是说当我们依次将t1, t2, t3加入队列中,实际上就绪状态只有t1这个线程,t2,t3则会被添加到队列中,当t1执行完毕后,在从队列中获取一个放到就绪队列。

    ----------天道酬勤----------------
  • 相关阅读:
    str.format格式化用法(通过{}来替代%)
    urlparse模块(专门用来解析URL格式)
    Socket原理与编程基础
    如何查询端口号和网址的ip地址?
    urlretrieve 如何给文件下载设置下载进度?
    判断URL是否支持断点续传?
    断点续传
    HTTP协议详解之User Agent篇
    HTTP协议详解之基本认证篇
    HTTP协议详解之请求篇
  • 原文地址:https://www.cnblogs.com/jiliunyongjin/p/15572216.html
Copyright © 2020-2023  润新知