Java进阶——多线程相关,实际应用中的积累,持续更新

news2025/1/18 17:09:57

在这里插入图片描述

目录

  • 多线程相关
    • CountDownLatch
      • 赛跑的案例
      • countDownLatch.await(300, TimeUnit.SECONDS);
  • Java其他进阶
    • Map的put方法
    • 只放一个元素的集合


多线程相关

CountDownLatch

案例:主线程的执行需要等待子线程执行完,等各个线程执行完毕后,主线程做收尾的工作

  • 初始化一个:final CountDownLatch latch = new CountDownLatch(3);
  • 线程池中的子线程调用 countDown方法进行减1;
  • 主线程启动后,等待子线程不断减1,直到为0后,主线程继续往下执行;
package com.tianju.myTest;

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

public class CountdownLatchTest1 {

    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(3);
        final CountDownLatch latch = new CountDownLatch(3);
        for (int i = 0; i < 3; i++) {
            Runnable runnable = new Runnable() {

                @Override
                public void run() {
                    try {
                        System. out.println("子线程" + Thread.currentThread().getName() + "开始执行");
                        Thread. sleep((long) (Math. random() * 10000));
                        System. out.println("子线程" + Thread.currentThread().getName() + "执行完成");
                        latch.countDown(); // 当前线程调用此方法,则计数减一
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            service.execute(runnable);
        }

        try {
            System. out.println("主线程" + Thread.currentThread().getName() + "等待子线程执行完成..." );
            latch.await(); // 阻塞当前线程,直到计时器的值为0
            System. out.println("主线程" + Thread.currentThread().getName() + "开始执行...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            service.shutdown();
        }
    }
}

赛跑的案例

案例2:4名选手参加赛跑,选手需要等待裁判发送指令;裁判发送完指令后,需要等所有选手到达终点;所有选手到达终点后,裁判汇总成绩。

  • 主线程:裁判发指令,裁判等选手到达终点,到达终点后,汇总成绩;
  • 子线程:每个选手需要阻塞在裁判发指令之前,主线程发指令后,子线程继续运行;此时主线程阻塞,所有子线程结束后,主线程继续运行

实现的思路

  • 定义两个CountDownLatch,一个为1,一个为4;
  • CountDownLatch(1),用来控制等待裁判指令,主线程先休眠,让出资源,让子线程获得cpu资源,子线程通过await 阻塞;
  • 主线程休眠结束后,对1进行-1,然后await 4 阻塞,触发子线程,子线程继续运行;
  • 子线程在运行过程中对于4 进行-1,等到值为0时,触发主线程的await 4 阻塞;
  • 主线程继续运行,裁判进行成绩的汇总

在这里插入图片描述

在这里插入图片描述

package com.tianju.myTest;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
// https://www.cnblogs.com/tstd/p/4987935.html
public class CountdownLatchTest2 {

    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();
        final CountDownLatch cdOrder = new CountDownLatch(1);
        final CountDownLatch cdAnswer = new CountDownLatch(4);
        for (int i = 0; i < 4; i++) {
            Runnable runnable = new Runnable() {
                public void run() {
                    try {
                        System.out.println("选手" + Thread.currentThread().getName() + "正等待裁判发布口令");
                        cdOrder.await(); // 线程都阻塞在这里等待释放
                        System.out.println("选手" + Thread.currentThread().getName() + "已接受裁判口令");
                        Thread.sleep((long) (Math. random() * 10000));
                        System.out.println("选手" + Thread.currentThread().getName() + "到达终点");
                        cdAnswer.countDown(); // 进行-1操作,4个线程都在操作CountDownLatch
                        System.out.println("cdAnswer---->:"+cdAnswer);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            service.execute(runnable);
        }
        try {
            Thread. sleep((long) (Math. random() * 10000));

            System. out.println("裁判" + Thread.currentThread ().getName() + "即将发布口令" );
            cdOrder.countDown();
            System. out.println("裁判" + Thread.currentThread ().getName() + "已发送口令,正在等待所有选手到达终点" );
            cdAnswer.await();
            System. out.println("所有选手都到达终点" );
            System. out.println("裁判" + Thread.currentThread ().getName() + "汇总成绩排名" );
        } catch (Exception e) {
            e.printStackTrace();
        }
        service.shutdown();

    }
}

countDownLatch.await(300, TimeUnit.SECONDS);

await方法的对比

  • 没有设置时间,会一直阻塞,直到countdown为0;
  • 设置了时间,在超过这个时间后,解除阻塞,返回false;

线程一直阻塞的情况

在这里插入图片描述

到达时间后,就解除阻塞,并返回false

在这里插入图片描述

-1成功,返回true

在这里插入图片描述

Java其他进阶

Map的put方法

  • Map 的 put 方法其实是有返回值的

在这里插入图片描述

package com.tianju.myTest;

import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * hashMap 的 put 方法其实是有返回值的
 */
public class ConHashMap {
    public static void main(String[] args) {
        ConcurrentHashMap<Object, Object> concurrentHashMap = new ConcurrentHashMap<>();
        // 如果有了键为 pet,还能往里面放
        concurrentHashMap.put("pet", 567);
        Object put = concurrentHashMap.put("pet", "task");
        System.out.println(put);
        if (put!=null){
            System.out.println("======== current key used! ========");
        }
        System.out.println(concurrentHashMap);

        HashMap<Object, Object> hashMap = new HashMap<>();
        hashMap.put("pet", 123);
        Object pet = hashMap.put("pet", 561);
        System.out.println(pet);
        System.out.println(hashMap);
    }
}

只放一个元素的集合

  • 基于内存或者业务的考虑,有时候集合只放一个元素,可以用collections下面的singleton集合

在这里插入图片描述

package com.tianju.myTest;

import java.util.Collections;
import java.util.List;

/**
 * 只能存放一个元素的 List,不会造成内存空间的浪费
 */
public class SingletonListTest {
    public static void main(String[] args) {
        String s = "hello, singleton";
        List<String> list = Collections.singletonList(s);
        list.add("second element");
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【图像分类】基于深度学习的垃圾分类系统的设计与实现(ResNet网络,附代码和数据集)

写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。(专栏订阅用户订阅专栏后免费提供数据集和源码一份,超级VIP用户不在服务范围之内,不想订阅专栏的兄弟们可以私信…

万字解析:十大排序(直接插入排序+希尔排序+选择排序+堆排序+冒泡排序+快速排序+归并排序+计数排序+基数排序+桶排序)

文章目录 十大排序排序算法复杂度及稳定性分析一、 排序的概念1.排序&#xff1a;2.稳定性&#xff1a;3.内部排序&#xff1a;4.外部排序&#xff1a; 二、插入排序1.直接插入排序2.希尔排序 三、选择排序1.直接选择排序方法一方法二直接插入排序和直接排序的区别 2.堆排序 四…

SpringBoot集成Swagger2登录功能和安全认证

本篇文章要实现的功能&#xff1a; 1.集成swagger2.集成swagger登录功能&#xff0c;访问 /swagger-ui.html需要先登录3.集成安全认证&#xff0c;访问接口时携带header 请求接口时携带了上一步输入的header参数和值 1.集成swagger jdk11&#xff0c;SpringBoot 2.7.13 pom…

redis运维(十四) hash缓存案例

一 缓存案例 ① 需求 ② 个人理解 策略&#xff1a;不更新缓存&#xff0c;而是删除缓存大部分观点认为&#xff1a;1、做缓存不应该是去更新缓存,而是应该删除缓存2、然后由下个请求去缓存,发现不存在后再读取数据库,写入redis缓存 高并发场景下,到底先更新缓存还是先更…

Android studio 迁移之后打开没反应

把Android studio由d盘迁移到c盘&#xff0c;点击没反应&#xff1b; 需要把C:\Users\xxxx\AppData\Roaming\Google\AndroidStudio2022.3 目录下的studio64.exe.vmoptions 修改为C:&#xff0c;删除该文件会导致无法安装app。 里面配置了一个

git常用命令(git github ssh)

目录 1、语法说明2、本地仓库相关操作建立一个git文件(git init)把工作区的文件添加到暂存区(git add)把暂存区的文件添加到本地仓库(git commit)查看暂存区和本地仓库中的文件(git ls-files)查看文件夹下所有文件的状态(git status)查看版本库中的提交记录(git log)恢复的文件…

Linux系统管理与服务器安全:构建稳健云数据中心

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在当今数字化时代&#xff0c;云数据中心已经成…

Program Header Table(转载)

程序头表与段表相互独立&#xff0c;由ELF文件头统一管理。 程序头表负责ELF文件从文件到加载后映像的映射关系&#xff0c;一般只有可执行文件包含。 1. segment和section segment: 程序头表项描述的对象称为segment&#xff0c;即elf文件加载后的数据块&#xff1b; 它提供…

【计算方法与科学建模】矩阵特征值与特征向量的计算(二):Jacobi 过关法及其Python实现(Jacobi 旋转法的改进)

文章目录 一、Jacobi 旋转法1. 基本思想2. 注意事项 二、Jacobi 过关法1. 基本思想2. 注意事项 三、Python实现迭代过程&#xff08;调试&#xff09; 矩阵的特征值&#xff08;eigenvalue&#xff09;和特征向量&#xff08;eigenvector&#xff09;在很多应用中都具有重要的数…

2023.11.22 homework

七年级数学 五年级数学 也不知道可以教到几年级&#xff0c;估计很快就教不动了。人生啊。

地图导航测试用例,你get了吗?

地图导航是我们经常使用的工具&#xff0c;能帮助我们指引前进的方向。 接下来&#xff0c;会从功能测试、UI测试、兼容测试、安全测试、网络测试、性能测试、易用性测试、文档和国际化语言测试8个方面来编写地图导航测试用例。 一 功能测试 输入起点和终点&#xff0c;验证…

五大资源之Service(可以固定IP)

Service可以看作是一组同类Pod对外访问接口,借助Service应用可以方便的实现服务发现与负载均衡 创建集群内部可以访问Service #暴露Service(也创建在了namespace dev下) [root@master ~]# kubectl expose deployment(pod控制器) nginx --name=svc-nginx1 --type=Cluste…

实在智能携“TARS大模型”入选“2023中国数据智能产业AI大模型先锋企业”

近日&#xff0c;由数据猿与上海大数据联盟联合主办的“2023企业数智化转型升级发展论坛”在上海圆满收官。 论坛颁奖典礼上&#xff0c;《2023中国数据智能产业AI大模型先锋企业》等六大榜单正式揭晓&#xff0c;旨在表彰在AI领域为数智化升级取得卓越成就和突出贡献的企业&am…

最新PHP熊猫头图片表情斗图生成源码

这是一款能生成熊猫头表情斗图的自适应系统源码&#xff0c;无论是在电脑还是手机上都可以正常使用&#xff01;这个源码集成了搜狗搜索图片接口&#xff0c;可以轻松地一键搜索数百万张图片&#xff0c;并且还包含了表情制作等功能模块。对于一些新站来说&#xff0c;这是一个…

代码规范之-理解ESLint、Prettier、EditorConfig

前言 团队多人协同开发项目&#xff0c;困扰团队管理的一个很大的问题就是&#xff1a;无可避免地会出现每个开发者编码习惯不同、代码风格迥异&#xff0c;为了代码高可用、可维护性&#xff0c;需要从项目管理上尽量统一和规范代码。理想的方式需要在项目工程化方面&#xff…

元素清空操作clear与选择操作check

元素清空操作clear与选择操作check clear() 作用 清空输入框的所有内容.clear() 等价于 .type("{selectall}{backspace}") 语法 .clear() .clear(options)option选项 元素选中操作check与uncheck check 语法 // 所有匹配到的选择框都会被选中一遍 .check()/…

【HarmonyOS】元服务卡片本地启动拉起加桌没问题,上架后拉起加桌时卡片展示异常

【关键字】 加桌选卡展示异常 、 2卡共用一个布局 、 代码混淆 【问题现象】 元服务卡片在本地启动拉起加桌时&#xff0c;多卡的选卡过程显示是没问题的。但是在上架后拉起加桌时&#xff0c;多卡的选卡过程卡片展示异常。 代码逻辑是通过创建卡片的时候判断卡片的尺寸大小…

Web前端—移动Web第四天(vw适配方案、vw和vh的基本使用、综合案例-酷我音乐)

版本说明 当前版本号[20231122]。 版本修改说明20231122初版 目录 文章目录 版本说明目录移动 Web 第四天01-vw适配方案vw和vh基本使用vw布局vh布局混用问题 02-综合案例-酷我音乐准备工作头部布局头部内容搜索区域banner 区域标题公共样式排行榜内容推荐歌单布局推荐歌单内…

生活如果真能像队列一样的话

生活如果真能像队列一样&#xff0c;那该多好啊。 —————————————————————————————————————————— 背包&#xff0c;队列 可以先看他们的API&#xff1a;都含有一个无参构造函数&#xff0c;添加单个元素的方法&#xff0c;测试集合…