• 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

  • 相关阅读:
    [零基础学IoT Pwn] 环境搭建
    unity 创建项目报错feature has expired (H0041),sentinel key not found (H0007)
    C/C++---------------LeetCode第1748.唯一元素的和
    阶段性总结:跨时钟域同步处理
    30分钟入门前端容器化
    H3C 防火墙策略
    ContentProvider与ContentResolver
    wget 命令的使用:HTTP文件下载、FTP文件下载--九五小庞
    20年前iPod改变了世界,20年后它变成了怀旧机器
    c++入门99题21-30
  • 原文地址:https://blog.csdn.net/qq_41915325/article/details/127108899