多线程---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 ❤️感谢大家点赞👍收藏⭐评论✍️ 问题描述:上传图片后,图片会变得很大,当点击的时候更是会顶开整个的容器的高跟宽 原因&#…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
