• 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

  • 相关阅读:
    放大器的输入、输出电压范围的理解
    Python 图形化界面基础篇:使用弹出窗口和对话框
    micropython与电机舵机(给初学者)
    原生 canvas 如何实现大屏?
    Java 反射
    2020华数杯全国大学生数学建模竞赛C题-脱贫帮扶绩效评价体系的构建与探究(二)(附MATLAB和Python代码)
    我用PYQT5做的第一个实用的上位机项目(四)
    万字详解JVM,让你一文吃透
    常见的7种分布式事务解决方案(2pc,3pc,Tcc,Seta、本地事务....)
    数商云采购系统对账结算功能介绍 | 缩短汽配企业结算周期,提高资金周转效率
  • 原文地址:https://blog.csdn.net/qq_41915325/article/details/127108899