多线程---JUC
文章目录
- 什么是JUC?
- Callable接口
- ReentrantLock
- ReentrantLock VS synchronized
- 原子类
- 线程池
- 信号量Semaphore
- CountDownLatch
什么是JUC?
JUC是:java.util.concurrent这个包名的缩写。它里面包含了与并发相关,即与多线程相关的很多东西。我们下面就来介绍这些东西。
Callable接口
Callable接口类似与Runnable接口:
Runnable接口:描述的任务是不带返回值的。
callable接口:描述的任务是带返回值的,存在的意义就是让我们获取到结果
让我们通过下面的代码来仔细体会一下不同
// 使用Runnable来计算 1+2+.....+1000static class Result{public int sum;public Object locker = new Object();}public static void main(String[] args) {Result result = new Result();//创建一个专门的线程来求和Thread thread = new Thread(){@Overridepublic void run() {for (int i = 0; i < 1000; i++){result.sum ++;}synchronized (result.locker){result.locker.notify();}}};thread.start();// 必须得等thread线程执行完了再打印synchronized (result.locker) {if (result.sum == 0){try {result.locker.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(result.sum);}}
// 使用callable来计算1+2+....+1000public static void main(String[] args) {//使用callable来定义一个任务Callable<Integer> callable = new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 0; i < 1000; i++){sum++;}return sum;}};// 用来接受callable任务作为参数FutureTask<Integer> futureTask = new FutureTask<>(callable);//Thread 里的参数没有callable类型 只有futuretask类型 所以需要创建一个futuretask类型来过渡Thread thread = new Thread(futureTask);thread.start();try {System.out.println(futureTask.get());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}
ReentrantLock
ReentrantLock,也是可重入锁。它的出现是为了补充synchronized(可重入锁)无法实现的一些操作。
它一共有三个核心的方法:
- tryLock:试试能不能加上锁,试成功了就加上锁;试失败了就放弃。还可以指定加锁的等待超时时间,超过时间则放弃加锁。
- lock:加锁
- unlock:解锁
ReentrantLock VS synchronized
- ReentrantLock必须手动调用lock()和unlock()方法,这样如果它们之间出现异常,unlock()方法就有可能调用不到,造成资源浪费。而synchronized则没有这个问题。
public static void main(String[] args) {// 和synchronized相比有三个优势 两个不同ReentrantLock reentrantLock = new ReentrantLock();try {reentrantLock.lock();}finally {//当在 lock和unlock 之间出现异常时 unlock就无法执行到 需要用到finally来必须执行//synchronized不存在这个问题 因为它只要出了代码块就一定会解锁reentrantLock.unlock();}}
- ReentrantLock是标准库的一个类,底层是基于Java实现的;synchronized是Java关键字,底层是通过JVM实现的(C++实现的)
- tryLock可以尝试加锁并且指定加锁的等待超时时间;synchronized会一直死等。在实际开发中,往往不使用死等。
- ReentrantLock可以实现公平锁,通过指定构造方法里的一个参数;synchronized是非公平锁。
ReentrantLock reentrantLock = new ReentrantLock(true);
- ReentrantLock是搭配Condition类实现通知唤醒操作的,唤醒操作可以指定唤醒哪一个线程;synchronized是搭配wait-notify实现通知唤醒操作的,唤醒操作是随机唤醒一个线程。
原子类
原子类的底层是基于CAS实现的,使用原子类最常见的场景就是多线程计数。
CAS操作前面已经非常详细的介绍过,点击此处可以查看浏览
//原子类 多用于计数//count.getAndIncrement = count++//count.incrementAndGer = ++count//count.getAndDecrement = count--//count.decrementAndGer = --countpublic static void main(String[] args) {AtomicInteger count = new AtomicInteger();Thread thread = new Thread(() -> {for (int i = 0; i < 50000; i++){//相当与count++;count.getAndIncrement();}});Thread thread1 = new Thread(() -> {for (int i = 0; i < 50000; i++){//相当于count++;count.getAndIncrement();}});thread.start();thread1.start();try {thread.join();thread1.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(count.get());}
线程池
前面已经非常详细的介绍过,点击此处可以查看浏览
信号量Semaphore
信号量的基本操作有两个:
P操作:申请一个资源
V操作:释放一个资源
信号量本身是一个计数器,表示可用资源的个数:
P操作申请一个资源,可用资源的个数就-1
V操作释放一个资源,可用资源的个数就+1
当计数为0时,继续进行P操作就会阻塞,直到其他线程执行V操作释放资源
// 信号量可以看成更广义的锁 锁就是一个信号量 可用资源数只有1public static void main(String[] args) throws InterruptedException {// 需要指定初始值 表示可用资源的个数Semaphore semaphore = new Semaphore(4);semaphore.acquire();System.out.println("申请资源");semaphore.acquire();System.out.println("申请资源");semaphore.acquire();System.out.println("申请资源");semaphore.release();System.out.println("释放资源");semaphore.release();System.out.println("释放资源");}
CountDownLatch
CountDownLatch使用的效果:类似于一个跑步比赛,当最后一个选手到达终点就结束。
使用CountDownLatch的时候,首先要设置一下有几个选手参赛,每个选手撞线了就调用一下countDown方法,当撞线次数达到选手的个数时,比赛就结束。
放到程序中理解:
比如:要下载一个很大的文件,把文件分成多部分分别下载。使用多线程执行下载任务,每个线程下载一部分,当所有的线程都下载完毕,整个线程就下载完毕了。
//CountDownLatchpublic static void main(String[] args) {// 设置任务的个数CountDownLatch downLatch = new CountDownLatch(10);for (int i = 0; i < 10; i++){Thread thread = new Thread(() -> {System.out.println("开始任务" + Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("任务结束" + Thread.currentThread().getName());downLatch.countDown();});thread.start();}try {downLatch.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("全部任务都结束");}
相关文章:
多线程---JUC
文章目录 什么是JUC?Callable接口ReentrantLockReentrantLock VS synchronized 原子类线程池信号量SemaphoreCountDownLatch 什么是JUC? JUC是:java.util.concurrent这个包名的缩写。它里面包含了与并发相关,即与多线程相关的很多…...
事务隔离级别
隔离级别 概念理解 事务的概念 事务是数据库管理系统中的一个基本单位,它代表了一组数据库操作。 事务是一个不可分割的工作单元,要么全部成功执行,要么全部失败回滚。 事务的目标是确保数据库的一致性、隔离性、持久性和原子性ÿ…...
centos7安装配置及Linux常用命令
目录 一.centos7的安装 1.1centos7的简介 1.2步骤 编辑 1.3登录 编辑 1.4MobaXterm使用 二.Linux常用命令&模式 1.1 常用命令 1.2 三种模式 命令模式 编辑模式 末行模式 1.3 命令使用&换源 换源 1.4 拍照备份 一.centos7的安装 1.1centos7的简…...
C语言调用lua
C语言是一种非常流行的编程语言,而Lua是一种基于C语言开发的脚本语言。相信大家都知道,Lua可以使用C语言来扩展其功能,进而实现更复杂的功能。而在Lua的各种实现中,luajit也是其中一种非常流行的实现。在本篇博客中,我…...
算法通关村第十二关黄金挑战——最长公共前缀问题解析
大家好,我是怒码少年小码。 最长公共前缀 LeetCode 14:编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。 示例: 输入:strs [“flower”,“flow”,“flight”]输出ÿ…...
Python运维学习Day02-subprocess/threading/psutil
文章目录 1. 检测网段在线主机2. 获取系统变量的模块 psutil 1. 检测网段在线主机 import subprocessdef checkIP(ip):cmd fping -n 1 -w 1 {ip}null open(nlll,modewb)status subprocess.call(cmd,shellTrue,stdoutnull,stderrnull)if status 0:print(f"主机[{ip}]在…...
开源库存管理系统InvenTree的安装
本文是应网友 shijie880500 要求折腾的; 什么是 InvenTree ? InvenTree 是一个开源的库存管理系统,提供强大的低级别库存控制和零件跟踪。InvenTree 系统的核心是 Python/Django 数据库后端,它提供了一个管理界面(基于…...
[双指针] (二) LeetCode 202.快乐数 和 11.盛最多水的容器
[双指针] (二) LeetCode 202.快乐数 和 11.盛最多水的容器 快乐数 202. 快乐数 题目解析 (1) 判断一个数是不是快乐数 (2) 快乐数的定义:将整数替换为每个位上的和;如果最终结果为1,就是快乐数 (3) 这个数可能变为1,也可能无…...
前端、HTTP协议(重点)
什么是前端 前端是所有跟用户直接打交道的都可以称之为是前端 比如:PC页面、手机页面、平板页面、汽车显示屏、大屏幕展示出来的都是前端内容 能够用肉眼看到的都是前端 为什么要学前端 学了前端以后我们就可以做全栈工程师(会后端、会前端、会DB、会运维等) 咱…...
软件开发项目文档系列之六概要设计:构建可靠系统的蓝图
概要设计是软件开发项目中至关重要的阶段,它为整个系统提供了设计蓝图和技术方向。它的重要性在于明确项目目标、规划系统结构、确定技术选择、识别风险、以及为团队提供共同的视角,确保项目在后续开发阶段按计划进行。概要设计的主要内容包括项目的背景…...
[C++]命名空间等——喵喵要吃C嘎嘎
希望你开心,希望你健康,希望你幸福,希望你点赞! 最后的最后,关注喵,关注喵,关注喵,大大会看到更多有趣的博客哦!!! 喵喵喵,你对我真的…...
安装ora2pg遇到如下问题
通过源码安装ora2pg成功后,查询帮助信息报错 [rootlocalhost bin]# ora2pg --help Cant locate open.pm in INC (you may need to install the open module) (INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/shar…...
x86-32-Linux下栈溢出攻击原理
在x86-32-Linux下构造一个栈溢出攻击 栈缓冲区溢出攻击:向栈上的数组写入超过数组长度的数据导致覆盖到正常数据{栈帧上的返回地址}。 IA-32下C函数调用约定: 调用者将参数从右向左入栈,构造参数call 指令短跳转,会将call指令下一…...
GPS学习(一):在ROS2中将GPS经纬度数据转换为机器人ENU坐标系,在RVIZ中显示坐标轨迹
文章目录 一、GPS模块介绍二、坐标转换转换原理参数解释: 增加回调函数效果演示 本文记录在Ubuntu22.04-Humbel中使用NMEA协议GPS模块的过程,使用国产ROS开发板鲁班猫(LubanCat )进行调试。 一、GPS模块介绍 在淘宝找了款性价比较高的轮趣科技GPS北斗双…...
chatgpt生成文本的底层工作原理是什么?
文章目录 🌟 ChatGPT生成文本的底层工作原理🍊 一、数据预处理🍊 二、模型结构🍊 三、模型训练🍊 四、文本生成🍊 总结 📕我是廖志伟,一名Java开发工程师、Java领域优质创作者、CSDN…...
javaEE -11(10000字HTML入门级教程)
一: HTML HTML 代码是由 “标签” 构成的. 例如: <body>hello</body>标签名 (body) 放到 < > 中大部分标签成对出现. 为开始标签, 为结束标签.少数标签只有开始标签, 称为 “单标签”.开始标签和结束标签之间, 写的是标签的内容. (h…...
LeetCode75——Day21
文章目录 一、题目二、题解 一、题目 1207. Unique Number of Occurrences Given an array of integers arr, return true if the number of occurrences of each value in the array is unique or false otherwise. Example 1: Input: arr [1,2,2,1,1,3] Output: true Ex…...
学习笔记---更进一步的双向链表专题~~
目录 1. 双向链表的结构🦊 2. 实现双向链表🐝 2.1 要实现的目标🎯 2.2 创建初始化🦋 2.2.1 List.h 2.2.2 List.c 2.2.3 test.c 2.2.4 代码测试运行 2.3 尾插打印头插🪼 思路分析 2.3.1 List.h 2.3.2 List.…...
vscode格式化代码, 谷歌风格, 允许短if同行短块同行, tab = 4舒适风格
ctrl ,输入format, 点开C风格设置 在这块内容输入{ BasedOnStyle: Chromium, IndentWidth: 4, ColumnLimit: 200, AllowShortIfStatementsOnASingleLine: true, AllowShortLoopsOnASingleLine: true} C_Cpp: Clang_format_fallback Style 用作回退的预定义样式的名称&#x…...
百度富文本上传图片后样式崩塌
🔥博客主页: 破浪前进 🔖系列专栏: Vue、React、PHP ❤️感谢大家点赞👍收藏⭐评论✍️ 问题描述:上传图片后,图片会变得很大,当点击的时候更是会顶开整个的容器的高跟宽 原因&#…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
