• java多线程保证顺序执行


    前言

    举例说明 比如要去冰箱里面拿牛奶,那么正常步骤是这样的。

    1、打开冰箱
    2、拿出牛奶
    3、关上冰箱

    代码实现是这样的:

        public static void main(String[] args) {
            Thread A = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("打开冰箱");
                }
            });
    
            Thread B = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("拿出牛奶");
                }
            });
    
            Thread C = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("关上冰箱");
                }
            });
    
            A.start();
            B.start();
            C.start();
        }
    

    但是我们运行之后会发现结果居然是这样的。什么鬼。
    在这里插入图片描述
    有小伙伴会问 代码执行不是由上往下的吗,我应该先做开冰箱的操作啊。

    那是因为多线程的执行和线程写的前后顺序无关,而是和CPU中的线程调度有关。

    线程是没有执行顺序的, 哪个线程抢到执行权,就哪个执行,其他线程等待。

    保证线程顺序执行的方法一:

    通过thread.join()方法

    代码实现如下:

        public static void main(String[] args) {
        
            Thread A = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("打开冰箱");
                }
            });
    
            Thread B = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        A.join();
                        System.out.println("拿出牛奶");
                    } catch (Exception e) {
    
                    }
                }
            });
    
            Thread C = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        B.join();
                        System.out.println("关上冰箱");
                    } catch (Exception e) {
    
                    }
                }
            });
    
            A.start();
            B.start();
            C.start();
        }
    

    另外也可以在启动线程的时候顺序的控制

        public static void main(String[] args) {
            try {
                Thread A = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("打开冰箱");
                    }
                });
    
                Thread B = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("拿出牛奶");
                    }
                });
    
                Thread C = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("关上冰箱");
                    }
                });
    
                A.start();
                A.join();
                B.start();
                B.join();
                C.start();
            }
            catch (Exception e)
            {
    
            }
    
        }
    

    保证线程顺序执行的方法二:

    使用单线程化的线程池newSingleThreadExecutor

    特点就是只有一个核心线程,无非核心线程,执行完立即回收。

    注意提交时候的顺序。

        public static void main(String[] args) {
            try {
                ExecutorService executor = Executors.newSingleThreadExecutor();
                Thread A = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("打开冰箱");
                    }
                });
    
                Thread B = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("拿出牛奶");
                    }
                });
    
                Thread C = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("关上冰箱");
                    }
                });
    
                executor.submit(A);
                executor.submit(B);
                executor.submit(C);
                executor.shutdown();
            }
            catch (Exception e)
            {
    
            }
    
        }
    

    除了这两种之外,也还有其他的方法,比如借助CountDownLatch等等。
    参考这篇文章 https://blog.csdn.net/m0_37825219/article/details/108962899

  • 相关阅读:
    8月20日计算机视觉理论学习笔记——图像分割
    kettle基础使用教程
    Pandas中的数据转换[细节]
    深度学习概念(术语):Fine-tuning、Knowledge Distillation, etc
    CANape XCP on Eth工程创建
    使用 AWS boto3 库从 s3 桶中批量下载数据
    分类预测 | Matlab实现基于MIC-BP-Adaboost最大互信息系数数据特征选择算法结合Adaboost-BP神经网络的数据分类预测
    【绝㊙️】三年开发内功心得
    【C++】STL之vector操作
    Arthas简介及IDEA插件快速入门
  • 原文地址:https://blog.csdn.net/qq_41915325/article/details/127108899