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

在这里插入图片描述

目录

  • 多线程相关
    • 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() {@Overridepublic 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(); // 阻塞当前线程,直到计时器的值为0System. 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个线程都在操作CountDownLatchSystem.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.mzph.cn/news/160259.shtml

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

相关文章

redis的高可用(主从复制和哨兵模式)

redis的高可用&#xff08;主从复制和哨兵模式&#xff09; redis的性能管理&#xff1a;redis的数据缓存在内存当中 INFO memory&#xff1a;查看redis内存使用情况 used_memory:1800800&#xff1a;redis中数据占用的内存 used_memory_rss:5783552&#xff1a;redis向操作…

Halcon Solution Guide I basics(3): Region Of Interest(有兴趣区域/找重点)

文章目录 文章专栏前言文章解读前言创建ROI案例1&#xff1a;直接截取ROI手动截取ROI 总结ROI套路获取窗口句柄截取ROI区域获取有效区域 Stop组合 文章专栏 Halcon开发 Halcon学习 练习项目gitee仓库 CSDN Major 博主Halcon文章推荐 前言 今天来看第三章内容&#xff0c;既然是…

QTableWidget——编辑单元格

文章目录 前言熟悉QTableWiget&#xff0c;通过实现单元格的合并、拆分、通过编辑界面实现表格内容及属性的配置、实现表格的粘贴复制功能熟悉QTableWiget的属性 一、[单元格的合并、拆分](https://blog.csdn.net/qq_15672897/article/details/134476530?spm1001.2014.3001.55…

docker、elasticsearch8、springboot3集成备忘

目录 一、背景 二、安装docker 三、下载安装elasticsearch 四、下载安装elasticsearch-head 五、springboot集成elasticsearch 一、背景 前两年研究了一段时间elasticsearch&#xff0c;当时也是网上找了很多资料&#xff0c;最后解决个各种问题可以在springboot上运行了…

Godot

前言 为什么要研究开源引擎 主要原因有&#xff1a; 可以享受“信创”政策的红利&#xff0c;非常有利于承接政府项目。中美脱钩背景下&#xff0c;国家提出了“信创”政策。这个政策的核心就是&#xff0c;核心技术上自主可控。涉及的产业包括&#xff1a;芯片、操作系统、数据…

【Django使用】md文档10大模块第5期:Django数据库增删改查和Django视图

Django的主要目的是简便、快速的开发数据库驱动的网站。它强调代码复用&#xff0c;多个组件可以很方便的以"插件"形式服务于整个框架&#xff0c;Django有许多功能强大的第三方插件&#xff0c;你甚至可以很方便的开发出自己的工具包。这使得Django具有很强的可扩展…

Vue项目 配置项设置

一、项目运行时浏览器自动打开 找到package.json文件 找到"sctipts"配置项 在"serve"配置项最后加上--open "scripts": {"serve": "vue-cli-service serve --open","build": "vue-cli-service build&quo…

Redis面试内容,Redis过期策略,Redis持久化方式,缓存穿透、缓存击穿和缓存雪崩,以及解决办法

文章目录 一、redis什么是RedisRedis使用场景1、缓存2、数据共享[分布式](https://so.csdn.net/so/search?q分布式&spm1001.2101.3001.7020)3、分布式锁4、全局ID5、计数器6、限流7、位统计 Redis有5中数据类型&#xff1a; SSHLZRedis中一个key的值每天12点过期&#xff…

Cookie、Session、CBV加装饰器的三种方法

【0】cookie、session和Token的发展史 【1】Cookie的形式 存储形式&#xff1a;k&#xff1a;v键值对存储位置&#xff1a;客户端缺点&#xff1a;不安全&#xff0c;信息可能会泄露 【2】session的形式 标识符&#xff0c;表示我是当前用户加密出来的数据对敏感信息进行加密…

排序算法-----快速排序(非递归实现)

目录 前言 快速排序 基本思路 非递归代码实现 前言 很久没跟新数据结构与算法这一栏了&#xff0c;因为数据结构与算法基本上都发布完了&#xff0c;哈哈&#xff0c;那今天我就把前面排序算法那一块的快速排序完善一下&#xff0c;前面只发布了快速排序递归算法&#xff0c;…

单链表相关面试题--3.链表的中间节点

3.链表的中间节点 876. 链表的中间结点 - 力扣&#xff08;LeetCode&#xff09; /* 解题思路&#xff1a; 通过快慢指针找到中间节点&#xff0c;快指针每次走两步&#xff0c;慢指针每次走一步&#xff0c;当快指针走到结尾的时候&#xff0c;慢指针正好走到中间位置 */ typ…

HTTPS协议的加密流程

目录 一&#xff0c;HTTPS是什么 二&#xff0c;两种加密方式 三&#xff0c;HTTPS的加密过程 3.1 引入对称加密 3.2 引入非对称加密 3.3 引入证书 一&#xff0c;HTTPS是什么 HTTPS也是一个应用层协议&#xff0c;它是在HTTP协议的基础上引入了一个加密层。因为HTTP协议…

51单片机按键控制LED灯亮灭的N个玩法

51单片机按键控制LED灯亮灭的N个玩法 1.概述 这篇文章介绍按键的使用&#xff0c;以及通过控制LED灯的小实验&#xff0c;发现按键中存在的问题&#xff0c;然后思考并解决这些问题。达到熟练使用按键控制元器件。 2.搭建硬件环境 1.硬件准备 名称型号数量单片机STC12C205…

Sleuth

Sleuth 一 引言 随着服务的越来越多&#xff0c;对调⽤链的分析会越来越复杂。它们之间的调⽤关系也许如下图&#xff1a; 问题&#xff1a; 1&#xff1a;微服务之间的调⽤错综复杂&#xff0c;⽤户发送的请求经历那些服务&#xff0c;调⽤链不清楚&#xff0c;没有⼀ 个⾃…

【SpringCloud微服务全家桶学习笔记-Hystrix(服务降级,熔断,接近实时的监控,服务限流等)】

服务雪崩 &#xff08;微服务面临的问题&#xff09; 多个微服务之间调用的时候&#xff0c;假设微服务A调用微服务B和微服务C&#xff0c;微服务B和微服务C又调用其它的微服务&#xff0c;这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用&…

sqlserver==索引解析,执行计划,索引大小

1创建测试表 -- 创建大型表 CREATE TABLE LargeTableWithIndex (ID int IDENTITY(1,1) PRIMARY KEY,IndexedColumn int,NonIndexedColumn nvarchar(255),OtherData nvarchar(255) );2插入测试数据 -- 使用 T-SQL 插入大量数据 DECLARE @i int = 1; WHILE @i <= 100000 -- …

Mac中LaTex无法编译的问题

最近在使用TexStudio时&#xff0c;遇到一个棘手的问题&#xff1a; 无法编译&#xff0c;提示如下&#xff1a; kpathsea: Running mktexfmt xelatex.fmt /Library/TeX/texbin/mktexfmt: kpsewhich -var-valueTEXMFROOT failed, aborting early. BEGIN failed–compilation a…

redis运维(十二) 位图

一 位图 ① 概念 1、说明&#xff1a;位图还是在操作字符串2、位图玩字符串在内存中存储的二进制3、ASCII字符通过映射转化为二进制4、操作的是字符串value ② ASCII字符铺垫 1、控制ASCII字符 2、ASCII可显示字符 ③ SETBIT 细节&#xff1a; setbit 命令的返回值是之…

git常用命令(git github ssh)

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