主线程等待所有线程结束之后再执行

如何让主线程等待所有线程结束之后再执行

1、Future的机制,使用Future.get()阻塞等待结果(Future,FutureTask)

2、CountDownLatch同步工具类,此类的作用就是一个线程等待所有线程结束之后再执行

3、CompletableFuture  与Future机制类似,同样是使用get阻塞等待结果,不过此类可以使任务并行合并以及串行,相当于是Future的增强版

4、线程池的isTerminated方法,当调用shutdown()方法后,并且所有提交的任务完成后才会返回为true

5、Thread的join方法,等待主线程结束

Future机制 

FutureTask

package com.alibaba.fescar.core.protocol.test;


import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class TestFuture {

    public static void main(String[] args) {

        FutureTask<Integer> futureTask = new FutureTask<Integer>(()-> {
            System.out.println("当前线程执行");
            return 1;
        });

        new Thread(futureTask).start();

        try {
            // 阻塞获取值
            Integer integer = futureTask.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("主线程执行");

    }


}

执行结果 

Future

package com.alibaba.fescar.core.protocol.test;


import java.util.concurrent.*;

public class TestFuture {

    public static void main(String[] args) {

        ExecutorService pool = Executors.newFixedThreadPool(1);

        Future<Integer> task = pool.submit(() -> {
            System.out.println("当前线程执行");
            return 1;
        });

        try {
            // 阻塞获取结果
            Integer integer= task.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        System.out.println("主线程执行");

    }


}

执行结果 

结果分析:这里借用线程池提交任务,程序没有退出,是因为线程池没有shutdown,熟悉下线程池的submit方法

<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);         
Future<?> submit(Runnable task);

如上所示,线程池接受Callable 和Runnable任务,返回Future接口的上转型对象,和FutureTask同理,

有关于Runnable、Future、Callable、FutureTask 请参考文章:

Runnable、Future、Callable、FutureTask

CountDownLatch 

package com.alibaba.fescar.core.protocol.test;

import java.util.concurrent.CountDownLatch;

public class TestCountDown {

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);

        new Thread(() -> {
            System.out.println("当前线程结束");
            latch.countDown();
        }).start();

        latch.await();
        System.out.println("主线程结束");

    }


}

 执行结果

 latch.dountDown()调用,计数器会减一,latch.await()会阻塞主线程直到0放行

CompletableFuture 

package com.alibaba.fescar.core.protocol.test;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class TestCompletableFuture {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        /**
         * supplyAsync与runAsync的区别在于:supplyAsync有返回值,而runAsync没有返回值
         */
        CompletableFuture<Integer> current1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程1执行");
            return 3;
        });

        /**
         * 合并两个任务,两个任务可以同时执行,都执行成功后,执行最后的BiFunction操作。
         */
        CompletableFuture<Integer> current2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程2执行");
            return 2;
        }).thenCombine(current1,(res1,res2)->res1 * res2);

        
        System.out.println(current2.get());

        System.out.println("主线程执行");
    }
}

执行结果 

 CompletableFuture实现了Future接口,当其get的时候同样阻塞主线程执行, CompletableFuture在于可以多任务串行,以及并行执行,操作空间更广

具体用法请参考文章:CompletableFuture用法

线程池的isTerminated方法

package com.alibaba.fescar.core.protocol.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestThreadPool{

    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(3);

        pool.execute(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        pool.execute(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        pool.shutdown();

        while (true) {
            if (pool.isTerminated()) {
                System.out.println("线程池中的任务执行结束");
                break;
            }
        }
        System.out.println("主线程结束");
    }
    
}

执行结果 

 

isTerminated,当调用shutdown()方法后,并且所有提交的任务完成后才会返回为true 

Thread的join方法

package com.alibaba.fescar.core.protocol.test;

public class TestThreadJoin {

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                System.out.println("t1执行");
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();

        Thread t2 = new Thread(() -> {
            try {
                System.out.println("t2执行");
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t2.start();

        t1.join();
        t2.join();
        System.out.println("主线程结束");
    }
}

执行结果

 Thread中的join方法,用于等待本线程结束,同时阻塞其他线程,也叫插队线程,yeild线程礼让,让出执行权,wait 线程等待,释放锁, sleep线程休眠 不会释放锁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/663515.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用Python爬取华为市场游戏类APP应用

文章目录 1. 写在前面2. 接口分析3. 爬虫开发4. 下载链接获取 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守…

统计信号处理-匹配滤波器实现与验证(matlab仿真)

什么是匹配滤波器 匹配滤波器是一种信号处理技术&#xff0c;它用于从噪声中提取信号&#xff0c;特别是在信号与噪声比率较低的情况下。匹配滤波器之所以存在&#xff0c;是因为它在信号检测和估计方面具有几个关键的优势&#xff1a; 最大化信噪比&#xff1a;匹配滤波器设计…

JVS低代码表单消息提示:从站内信到钉钉全覆盖,适应各类应用场景

表单消息提示配置 表单消息发送方式分为站内信、公众号、企业微信、钉钉和邮件。 站内信发送是指系统内部之间发送消息&#xff0c;用户登录系统后以弹窗形式在桌面右下角提示。 公众号发送消息则是用户在系统个人中心绑定微信后通过公众号接收消息。 企业微信、钉钉和邮件…

【Docker】宝塔创建Docker容器配置nginx

前言 本篇是我入门docker的第一篇&#xff0c;由于docker具有很好的移植性&#xff0c;易于安装&#xff0c;开箱即用&#xff1b;签约的公司项目开发需要我进行学习&#xff0c;否则money减半&#xff0c;5555~ 百度找了一圈&#xff0c;只有关于docker怎么装宝塔服务器的却没…

运算符重载(下)

目录 前置和后置重载前置的实现Date& Date::operator()代码 后置的实现Date Date::operator(int )代码 前置--和后置--重载前置--的实现Date& Date::operator--( )代码 后置--的实现Date Date::operator--(int )代码 流插入运算符重载流插入运算符重载的实现流提取运算…

1、css3 动态button展示学习

效果图&#xff1a; 1、首先创建html代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title…

LNMP分布式搭建

一、准备三台主机 192.168.100.11 mysql 192.168.100.12 nginx 192.168.100.13 php 二、关闭防火墙及安全策略 systemctl stop firewalld setenforce 0 三、安装nginx&#xff08;192.168.100.11&#xff09; 1、添加nginx源 vim /etc/yum.repos.d/ng…

数据库系统概念(第七周 第一堂)(E-R模型)

目录 前言 基本概念 观点与模型 作用与要求 E-R模型元素 实体&#xff08;entity&#xff09; 实体集&#xff08;entity set&#xff09; 属性&#xff08;attribute&#xff09; 域&#xff08;domain&#xff09; 码 &#xff08;key&#xff09; 联系 &#x…

allure测试报告用例数和 pytest执行用例数不相同问题

我出现的奇怪问题&#xff1a; pytest执行了9条用例&#xff0c;但是测试报告确只显示3条用例 我将其中的一个代码删除后&#xff0c;发现allure测试报告又正常了 我觉得很奇怪这个代码只是删除了二维数组的第一列&#xff0c;我检查了半天都找不到问题&#xff0c;只有降低版本…

优选算法一:双指针算法与练习(移动0)

目录 双指针算法讲解 移动零 双指针算法讲解 常见的双指针有两种形式&#xff0c;一种是对撞指针&#xff0c;一种是快慢指针。 对撞指针&#xff1a;一般用于顺序结构中&#xff0c;也称左右指针。 对撞指针从两端向中间移动。一个指针从最左端开始&#xff0c;另一个从最…

云计算与 openstack

文章目录 一、 虚拟化二、云计算2.1 IT系统架构的发展2.2 云计算2.3 云计算的服务类型 三、Openstack3.1 OpenStack核心组件 一、 虚拟化 虚拟化使得在一台物理的服务器上可以跑多台虚拟机&#xff0c;虚拟机共享物理机的 CPU、内存、IO 硬件资源&#xff0c;但逻辑上虚拟机之…

Python魔法之旅-魔法方法(04)

目录 一、概述 1、定义 2、作用 二、主要应用场景 1、构造和析构 2、操作符重载 3、字符串和表示 4、容器管理 5、可调用对象 6、上下文管理 7、属性访问和描述符 8、迭代器和生成器 9、数值类型 10、复制和序列化 11、自定义元类行为 12、自定义类行为 13、类…

【香橙派 AIpro】新手保姆级开箱教程:Linux镜像+vscode远程连接

香橙派 AIpro 开发板 AI 应用部署测评 写在最前面一、开发板概述官方资料试用印象适用场景 二、详细开发前准备步骤1. 环境准备2. 环境搭建3. vscode安装ssh插件4. 香橙派 AIpro 添加连接配置5. 连接香橙派 AIpro6. SSH配置 二、详细开发步骤1. 登录 juypter lab2. 样例运行3. …

Windows11 安装Oracle11gR2

一、下载Oracle 11gR2 安装包下载地址&#xff1a;Database Software Downloads | Oracle 下载两个压缩包&#xff0c;下载完成后解压缩到同一个目录。 二、安装Oracle 11gR2 Oracle安装是单程票&#xff0c;因为Oracle卸载特别麻烦&#xff0c;因此最好一次通过。 2.1 安…

排八字软件有哪些?

排八字软件有哪些&#xff1f;在市面上有很多排八字的软件可供选择&#xff0c;其中一些比较知名的有&#xff1a; 无敌八字排盘软件&#xff1a;这是一款功能强大的八字排盘软件&#xff0c;提供详细的八字解析和命理分析服务&#xff0c;且完全免费。 网易星盘&#xff1a;网…

【JAVA |String类】JAVA中的String类常见用法详解

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; &#x1f388;丠丠64-CSDN博客&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起…

500元以内的蓝牙耳机哪个牌子好?首推四大热门品牌盘点

在500元以内的预算范围内&#xff0c;蓝牙耳机试市场上还是有很多可以选择的&#xff0c;它们以出色的音质、舒适的佩戴体验和稳定的连接性能赢得了消费者的青睐&#xff0c;作为一个蓝牙耳机的重度使用者&#xff0c;下也用过不少的500元以内的蓝牙耳机&#xff0c;下面就给大…

小白跟做江科大32单片机之光敏传感器控制蜂鸣器

代码部分 1.思路 通过光敏电阻&#xff0c;控制蜂鸣器的发声 2.butter.h代码 #ifndef _BUTTER__H #define _BUTTER__H void butter_Init(void); void butter_on(void); void butter_off(void); #endif 3.butter.c代码 #include "stm32f10x.h" void butter…

React-组件通信

组件通信 概念&#xff1a;组件通信就是组件之间的数据传递&#xff0c;根据组件嵌套关系的不同&#xff0c;有不同的通信方法 父传子 基础实现 实现步骤&#xff1a; 1.父组件传递数据-在子组件标签上绑定属性 2.子组件接收数据-子组件通过props参数接收数据 props说明 1.…

【C++题解】1446. 人口增长问题

问题&#xff1a;1446. 人口增长问题 类型&#xff1a;循环应用 题目描述&#xff1a; 我国现有 x 亿人口&#xff0c;按照每年 0.1% 的增长速度&#xff0c;n 年后将有多少人&#xff1f; 输入&#xff1a; 一行&#xff0c;包含两个整数 x 和 n &#xff0c;分别是人口基…