多线程---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 ❤️感谢大家点赞👍收藏⭐评论✍️ 问题描述:上传图片后,图片会变得很大,当点击的时候更是会顶开整个的容器的高跟宽 原因&#…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
