JUC(java.util.concurrent) 的常见类
1.ReentrantLock
可重入互斥锁. 和 synchronized 定位类似, 都是用来实现互斥效果, 保证线程安全.
ReentrantLock 也是可重入锁. "Reentrant" 这个单词的原意就是 "可重入.
ReentrantLock 的用法:
- lock(): 加锁, 如果获取不到锁就死等.
- trylock(超时时间): 加锁, 如果获取不到锁, 等待一定的时间之后就放弃加锁.
- unlock(): 解锁
ReentrantLock lock = new ReentrantLock();-----------------------------------------lock.lock();try {// working} finally {lock.unlock();}
ReentrantLock 和 synchronized 的区别:
- synchronized 是一个关键字, 是 JVM 内部实现的(大概率是基于 C++ 实现). ReentrantLock 是标准库的一个类, 在 JVM 外实现的(基于 Java 实现).
- synchronized 使用时不需要手动释放锁. ReentrantLock 使用时需要手动释放. 使用起来更灵活,但是也容易遗漏 unlock.
- synchronized 在申请锁失败时, 会死等. ReentrantLock 可以通过 trylock 的方式等待一段时间就放弃.
- synchronized 是非公平锁, ReentrantLock 默认是非公平锁. 可以通过构造方法传入一个 true 开启公平锁模式.
- 更强大的唤醒机制. synchronized 是通过 Object 的 wait / notify 实现等待-唤醒. 每次唤醒的是一个随机等待的线程. ReentrantLock 搭配 Condition 类实现等待-唤醒, 可以更精确控制唤醒某个指定的线程
如何选择使用哪个锁?
- 锁竞争不激烈的时候, 使用 synchronized, 效率更高, 自动释放更方便.
- 锁竞争激烈的时候, 使用 ReentrantLock, 搭配 trylock 更灵活控制加锁的行为, 而不是死等.
- 如果需要使用公平锁, 使用 ReentrantLock.
既然有了synchronized为啥还有ReentrantLock?
ReentrantLock提供了更丰富的功能!!能做到synchronized做不到的事情!!
1.ReentrantLock 提供了一个公平锁的实现版本~~(构造方法中,通过一个标志位,指定是公平锁,还是非公平锁)
2.ReentrantLock提供了一个tryLock操作~~
- trylock 能够指定一个加锁的等待时间.
- synchronized如果拿不到锁,就死等..
- trylock 能指定一个最大的等待时间~~
2.原子类
原子类内部用的是 CAS 实现,所以性能要比加锁实现 i++ 高很多。原子类有以下几个
- AtomicBoolean
- AtomicInteger
- AtomicIntegerArray
- AtomicLong
- AtomicReference
- AtomicStampedReference
以 AtomicInteger 举例,常见方法有
addAndGet(int delta); i += delta;
decrementAndGet(); --i;
getAndDecrement(); i--;
incrementAndGet(); ++i;
getAndIncrement(); i++;
3.线程池
虽然创建销毁线程比创建销毁进程更轻量, 但是在频繁创建销毁线程的时候还是会比较低效.
线程池就是为了解决这个问题. 如果某个线程不再使用了, 并不是真正把线程释放, 而是放到一个 "池子"中, 下次如果需要用到线程就直接从池子中取, 不必通过系统来创建了
ExecutorService 和 Executors
- ExecutorService 表示一个线程池实例.
- Executors 是一个工厂类, 能够创建出几种不同风格的线程池.
- ExecutorService 的 submit 方法能够向线程池中提交若干个任务.
ExecutorService pool = Executors.newFixedThreadPool(10);pool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello");}});
Executors 创建线程池的几种方式
- newFixedThreadPool: 创建固定线程数的线程池
- newCachedThreadPool: 创建线程数目动态增长的线程池.
- newSingleThreadExecutor: 创建只包含单个线程的线程池.
- newScheduledThreadPool: 设定 延迟时间后执行命令,或者定期执行命令. 是进阶版的 Timer.
Executors 本质上是 ThreadPoolExecutor 类的封装
ThreadPoolExecutor
ThreadPoolExecutor 提供了更多的可选参数, 可以进一步细化线程池行为的设定
理解 ThreadPoolExecutor 构造方法的参数
把创建一个线程池想象成开个公司. 每个员工相当于一个线程
- corePoolSize: 正式员工的数量. (正式员工, 一旦录用, 永不辞退)
- maximumPoolSize: 正式员工 + 临时工的数目. (临时工: 一段时间不干活, 就被辞退).
- keepAliveTime: 临时工允许的空闲时间.
- unit: keepaliveTime 的时间单位, 是秒, 分钟, 还是其他值.
- workQueue: 传递任务的阻塞队列
- threadFactory: 创建线程的工厂, 参与具体的创建线程工作.
- RejectedExecutionHandler: 拒绝策略, 如果任务量超出公司的负荷了接下来怎么处理.
- AbortPolicy(): 超过负荷, 直接抛出异常.
- CallerRunsPolicy(): 调用者负责处理
- DiscardOldestPolicy(): 丢弃队列中最老的任务.
- DiscardPolicy(): 丢弃新来的任务.
代码示例:
ExecutorService pool = new ThreadPoolExecutor(1, 2, 1000, TimeUnit.MILLISECONDS,new SynchronousQueue<Runnable>(),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());for (int i = 0; i < 3; i++) {pool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello");}});
信号量 Semaphore
信号量, 用来表示 "可用资源的个数". 本质上就是一个计数器.
理解信号量
可以把信号量想象成是停车场的展示牌: 当前有车位 100 个. 表示有 100 个可用资源.
当有车开进去的时候, 就相当于申请一个可用资源, 可用车位就 -1 (这个称为信号量的 P 操作)
当有车开出来的时候, 就相当于释放一个可用资源, 可用车位就 +1 (这个称为信号量的 V 操作)
如果计数器的值已经为 0 了, 还尝试申请资源, 就会阻塞等待, 直到有其他线程释放资源.
Semaphore 的 PV 操作中的加减计数器操作都是原子的, 可以在多线程环境下直接使用.
代码示例:
- 创建 Semaphore 示例, 初始化为 4, 表示有 4 个可用资源.
- acquire 方法表示申请资源(P操作), release 方法表示释放资源(V操作)
- 创建 20 个线程, 每个线程都尝试申请资源, sleep 1秒之后, 释放资源. 观察程序的执行效果.
package thread2;import java.util.concurrent.Semaphore;public class Test10 {public static void main(String[] args) {Semaphore semaphore = new Semaphore(4);Runnable runnable = new Runnable() {@Overridepublic void run() {try {System.out.println("申请资源");semaphore.acquire();System.out.println("我获取到资源了");Thread.sleep(1000);System.out.println("我释放资源了");semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}}};for (int i = 0; i < 20; i++) {Thread t = new Thread(runnable);t.start();}}
}
CountDownLatch
同时等待 N 个任务执行结束.
好像跑步比赛,10个选手依次就位,哨声响才同时出发;所有选手都通过终点,才能公布成绩。
package thread4;import java.util.concurrent.CountDownLatch;public class Test1 {public static void main(String[] args) throws InterruptedException {CountDownLatch countDownLatch = new CountDownLatch(10);for (int i = 0; i < 10; i++) {Thread t = new Thread(() -> {try {Thread.sleep(2);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("选手撞线了!" + Thread.currentThread().getName());countDownLatch.countDown();});t.start();}countDownLatch.await();System.out.println("比赛结束!");}
}
线程同步的方式有哪些?
synchronized, ReentrantLock, Semaphore 等都可以用于线程同步
为什么有了 synchronized 还需要 juc 下的 lock?
以 juc 的 ReentrantLock 为例,
- synchronized 使用时不需要手动释放锁. ReentrantLock 使用时需要手动释放. 使用起来更灵活,
- synchronized 在申请锁失败时, 会死等. ReentrantLock 可以通过 trylock 的方式等待一段时间就放弃.
- synchronized 是非公平锁, ReentrantLock 默认是非公平锁. 可以通过构造方法传入一个true 开启公平锁模式.
- synchronized 是通过 Object 的 wait / notify 实现等待-唤醒. 每次唤醒的是一个随机等待的线程. ReentrantLock 搭配 Condition 类实现等待-唤醒, 可以更精确控制唤醒某个指定的线程.
AtomicInteger 的实现原理是什么?
基于 CAS 机制. 伪代码如下:
class AtomicInteger {private int value;public int getAndIncrement() {int oldValue = value;while (CAS(value, oldValue, oldValue + 1) != true) {oldValue = value;}return oldValue;}}
信号量听说过么?之前都用在过哪些场景下?
信号量, 用来表示 "可用资源的个数". 本质上就是一个计数器.
使用信号量可以实现 "共享锁", 比如某个资源允许 3 个线程同时使用, 那么就可以使用 P 操作作为
加锁, V 操作作为解锁, 前三个线程的 P 操作都能顺利返回, 后续线程再进行 P 操作就会阻塞等待,
直到前面的线程执行了 V 操作.
解释一下 ThreadPoolExecutor 构造方法的参数的含义
相关文章:
JUC(java.util.concurrent) 的常见类
1.ReentrantLock 可重入互斥锁. 和 synchronized 定位类似, 都是用来实现互斥效果, 保证线程安全. ReentrantLock 也是可重入锁. "Reentrant" 这个单词的原意就是 "可重入. ReentrantLock 的用法: lock(): 加锁, 如果获取不到锁就死等.trylock(超时时间):…...
Angular4 中 ckeditor5 插件的使用
Angular4 中 ckeditor5 插件的使用 0 环境、新建项目 环境: Windows10Angular/cli1.4.10(安装 Angular 的过程略过,Angular4 版本比较古老,这也导致项目安装插件及其他操作比较麻烦) 1. ckeditor5 官方用法 基础用…...
[python刷题模板] 前缀函数/next数组/kmp算法
[python刷题模板] 前缀函数/next数组/kmp算法 一、 算法&数据结构1. 描述2. 复杂度分析3. 常见应用4. 常用优化二、 模板代码1. 裸前缀函数2. 树上kmp3. 裸kmp三、其他四、更多例题五、参考链接一、 算法&数据结构 1. 描述 前缀函数和next数组基本上是一个东西&#…...
rust 程序设计语言入门(1)
本文是阅读《Rust程序设计语言》的学习记录,配合视频《Rust编程语言入门教程》食用更佳 环境搭建 windows下载rustup_init.exe,点击安装,默认选择msvc的toolchain,一路default即可 解决下载慢的问题,在powershell中修…...
基于蜣螂算法改进的LSTM预测算法-附代码
基于蜣螂算法改进的LSTM预测算法 文章目录基于蜣螂算法改进的LSTM预测算法1.数据2.LSTM模型3.基于蜣螂算法优化的LSTM4.测试结果5.Matlab代码摘要:为了提高LSTM数据的预测准确率,对LSTM中的参数利用蜣螂搜索算法进行优化。1.数据 采用正弦信号仿真数据&…...
Python安全开发——Scapy流量监控模块watchdog
目录 Python蓝队项目说明 (一)Python-蓝队项目-Scapy流量分析 0x01 Scapy参数介绍...
阶段二5_集合ArrayList
一.对象数组 1.对象数组使用案例 需求:将(张三,23)(李四,24)(王五,25) 封装为3个学生对象并存入数组 随后遍历数组,将学生信息输出在控制台 思路…...
十一、Python——匿名函数
1.匿名函数:简化函数定义 2.格式 lambda 参数1,参数2…:运算 3.匿名函数特点 不需要指明函数名定义只有一条语句函数体必须是一个表达式不能显示使用return 4.匿名函数实现求和 s lambda a,b:a b result s(1,2) print(result) # 35.匿名函数作…...
数组常使用的方法
1. join (原数组不受影响)该方法可以将数组里的元素,通过指定的分隔符,以字符串的形式连接起来。返回值:返回一个新的字符串const arr[1,3,4,2,5]console.log(arr.join(-);//1-3-4-2-52. push该方法可以在数组的最后面,添加一个或者多个元素结构: arr.push(值)返回值…...
2023华为软件测试笔试面试真题,抓紧收藏不然就看不到了
一、选择题 1、对计算机软件和硬件资源进行管理和控制的软件是(D) A.文件管理程序 B.输入输出管理程序 C.命令出来程序 D.操作系统 2、在没有需求文档和产品说明书的情况下只有哪一种测试方法可以进行的(A) A.错误推测法测…...
洛谷2月普及组(月赛)
🌼小宇(治愈版) - 刘大拿 - 单曲 - 网易云音乐 OI赛制且难度对标蓝桥杯省赛(😥真难,第三题做了几百年,第四题只敢骗骗分) 花了10块钱🙃 买官网的思路,结果…...
【博学谷学习记录】超强总结,用心分享 | 架构师 Spring源码学习总结
文章目录Spring的循环依赖1.循环依赖的定义&&原因2.循环依赖的场景1.构造器注入引起循环依赖2.Field属性setter注入的循环依赖3.循环依赖解决思路4.三级缓存5.面试题[三级缓存]AOP源码深度剖析概述Spring AOP的前世今生实现机制**JDK 动态代理****CGLIB 代理**流程总结…...
Linux C/C++ timeout命令实现(运行具有时间限制)
Linux附带了大量命令,每个命令都是唯一的,并在特定情况下使用。Linux timeout命令的一个属性是时间限制。可以为任何命令设置时间限制。如果时间到期,命令将停止执行。 如何使用timeout命令 我们将解释如何使用Linux timeout命令 timeout […...
西湖论剑初赛web wp
Node Magical Login 简单的js代码审计。 Flag分成了两部分。 第一部分: 这里就简单的判断了一下user是否等于admin,直接绕过。 第二部分: checkcode ! “aGr5AtSp55dRacer”,让其为真,利用数组绕过。 Flag为&#x…...
【YOLOv8/YOLOv7/YOLOv5系列算法改进NO.55】融入美团最新QARepVGG
文章目录 前言一、解决问题二、基本原理三、添加方法四、总结前言 作为当前先进的深度学习目标检测算法YOLOv8,已经集合了大量的trick,但是还是有提高和改进的空间,针对具体应用场景下的检测难点,可以不同的改进方法。此后的系列文章,将重点对YOLOv8的如何改进进行详细…...
Flutter Windows端打包并生成可安装文件流程
Windows打包 1.首先安装visual Studio 下载地址:https://visualstudio.microsoft.com/zh-hans/ 下载成功后按照下图勾选桌面应用和移动应用下的使用C的桌面开发,勾选右侧安装详细信息中的windows 11/10 sdk 中的任意一个完成安装即可 2.打包Windows …...
凸优化学习:PART3凸优化问题(持续更新)
凸优化问题 凸优化问题的广义定义: 目标函数为凸函数约束集合为凸集 一、优化问题 基本用语 一般优化问题的描述: minimizef0(x)subject to fi(x)⩽0,i1,⋯,mhi(x)0,i1,⋯,p(1)\begin{array}{ll} \operatorname{minimize} & f_0(x) \\ \text { s…...
[ue4] 着色器绑定(Shader Binding)
当我们在ue4中制作了一个美术材质之后,引擎本身会为我们做很多事情,它会把结点翻译为hlsl,生成多个shader变体,并在多个mesh pass中去选择性的调用所需的shader,其中一个重要的过程就是获取shader绑定的数据。 本文将主…...
Rust语言之迭代器
文章目录Rust迭代器Rust迭代器的实现Iterator特型IntoIterator特型for循环与迭代器迭代器类型再看for循环实现自定义迭代器方式一方式二相关参考Rust迭代器 Rust语言内置了迭代器模式,用于实现对一个项的序列进行特定的处理,通常配合for循环使用。当我们…...
TreeSet 与 TreeMap And HashSet 与 HashMap
目录 Map TreeMap put()方法 : get()方法 : Set> entrySet() (重) : foreach遍历 : Set 哈希表 哈希冲突 : 冲突避免 : 冲突解决 ---- > 比散列(开放地址法) : 开散列 (链地址法 . 开链法) 简介 : 在Java中 , TreeSet 与 TreeMap 利用搜索树实现 Ma…...
Java围棋游戏的设计与实现
技术:Java等摘要:围棋作为一个棋类竞技运动,在民间十分流行,为了熟悉五子棋规则及技巧,以及研究简单的人工智能,决定用Java开发五子棋游戏。主要完成了人机对战和玩家之间联网对战2个功能。网络连接部分为S…...
第七十三章 使用 irisstat 实用程序监控 IRIS - 使用选项运行 irisstat
文章目录第七十三章 使用 irisstat 实用程序监控 IRIS - 使用选项运行 irisstat使用选项运行 irisstatirisstat Options第七十三章 使用 irisstat 实用程序监控 IRIS - 使用选项运行 irisstat 使用选项运行 irisstat 不带选项运行 irisstat 会生成基本报告。通常,…...
【博客619】PromQL如何实现Left joins以及不同metrics之间的复杂联合查询
PromQL如何实现Left joins以及不同metrics之间的复杂联合查询 1、场景 我们需要在PromQL中实现类似SQL中的连接查询: SELECT a.value*b.value, * FROM a, b2、不同metrics之间的复杂联合查询 瞬时向量与瞬时向量之间进行数学运算: 例如:根…...
Win11自定义电脑右下角时间显示格式
Win11自定义电脑右下角时间显示格式 一、进入附加设置菜单 1、进入控制面板,选择日期和时间 2、选择修改日期和时间 3、选择修改日历设置 4、选择附加设置 二、自定义时间显示出秒 1、在选项卡中,选时间选项卡 2、在Short time的输入框中输入H:m…...
TrueNas篇-trueNas Scale安装
安装TrueNAS Scale 在尝试trueNas core时发下可以成功安装,但是一直无法成功启动,而且国内对我遇见的错误几乎没有案例,所以舍弃掉了,而且trueNas core是基于Linux的,对Linux的生态好了很多,还可以可以在t…...
element表单搜索框与表格高度自适应
一般在后台管理系统中,表单搜索框和表格的搭配是非常常见的,如下所示: 在该图中,搜索框有五个,分为了两行排列。但根据大多数的UI标准,搜索框默认只显示一行,多余的需要进行隐藏。此时的页面被…...
MySQL使用技巧整理
title: MySQL使用技巧整理 date: 2021-04-11 00:00:00 tags: MySQL categories:数据库 重建索引 索引可能因为删除,或者页分裂等原因,导致数据页有空洞,重建索引的过程会创建一个新的索引,把数据按顺序插入,这样页面…...
七大设计原则之里氏替换原则应用
目录1 里氏替换原则2 里氏替换原则应用1 里氏替换原则 里氏替换原则(Liskov Substitution Principle,LSP)是指如果对每一个类型为 T1 的对象 o1,都有类型为 T2 的对象 o2,使得以 T1 定义的所有程序 P 在所有的对象 o1 都替换成 o2 时,程序 P…...
1行Python代码去除图片水印,网友:一干二净
大家好,这里是程序员晚枫。 最近小明在开淘宝店(店名:爱吃火锅的少女),需要给自己的原创图片加水印,于是我上次给她开发了增加水印的功能:图片加水印,保护原创图片,一行…...
Connext DDS属性配置参考大全(2)
DDSSecure安全com.rti.servcom.rti.serv.load_plugin...
网站规划与建设周正刚/互联网营销顾问是做什么的
- 基础: 下载安装 声明变量的方法 数据的三种基础类型:bool,数字,string 数据类型:数组和切片 数据类型:Maps 条件判断以及循环 函数 包管理 package 指针 结构体- 初步进阶&am…...
知行网站建设/百度推广怎么添加关键词
为什么80%的码农都做不了架构师?>>> 首先App端把上传的图片使用base64进行编码,然后传给后台PHP处理,再进行base64解码,然后再利用file_put_contents这个函数把它写入到文件夹里面即可,代码如下࿱…...
wordpress 时间轴主题/网页设计制作
session并不是浏览器关闭时销毁的,而是在session失效的时候销毁下列代码就是监测session创建、销毁package com.my.count;import javax.servlet.http.*;public class SessionCounter implements HttpSessionListener {private static int activeSessions 0;//sessi…...
吉林省网站建设行业需求分析/十大引擎网址
题目:写一个函数返回参数二进制中 1 的个数比如: 15 0000 1111 4 个 1程序原型:int count_one_bits(unsigned int value){// 返回 1的位数 }解题思路:首先写出这个数字的二进制序列并且定义一个计数器,由于数字在计算机…...
手表特卖网站/石家庄seo代理商
git clone https://github.com.cnpmjs.org/xxx/xxxx.git...
关于网站设计与建设的论文/开通网站需要多少钱
比如: 给定学生和成绩: ‘小黑’: 80, ‘小王’: 90, ‘小杨’: 85, ‘小白’: 80 将其按照升序排列输出: 小黑:80 小白:80 小杨:85 小王:90 实现: 方法1:存到一个对象里,对对象的键利用sort排序 let o…...