JUC的常见类

目录

Callable

ReentrantLock

Semaphore

CountDownLatch


JUC java.util.concurrent,其中存放了一些进行多线程编程时有用的类

Callable

Callable是一个接口,在我们实现Runnable创建线程时,Runnable关注的是其过程,而不关注其执行结果(其返回值为void),而Callable会关注执行结果,Callable提供了call方法,其返回值就是线程执行任务得到的结果

因此,当我们在编写多线程代码时,希望得到线程种代码的返回值时,就可以使用Callable

例如:一个线程需要实现 1 + 2 + 3 + ... + 100,并返回其结果

若我们使用实现Runnable的方式创建线程时:

public class Demo1 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(new Runnable() {@Overridepublic void run() {int ret = 0;for (int i = 1; i <= 100; i++) {ret += i;}}});t.start();t.join();}
}

若此时主线程需要获取到其计算结果,则需要使用一个成员变量来保存结果

public class Demo1 {private static int sum = 0;public static void main(String[] args) throws InterruptedException {Thread t = new Thread(new Runnable() {@Overridepublic void run() {int ret = 0;for (int i = 1; i <= 100; i++) {ret += i;}sum = ret;//保存结果}});t.start();t.join();System.out.println(sum);}
}

而若我们使用Callable时:

Callable<V> 其中泛型参数表示返回值的类型
        Callable<Integer> callable = new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int ret = 0;for (int i = 1; i <= 100; i++) {ret += i;}return ret;}};

此时就不必引入额外的成员变量了,直接使用返回值即可

然而,Thread未提供构造函数来传入callable

此时,我们需要使用 FutureTask 来作为Thread和callable的“粘合剂”

将callable实例使用FutureTask包装一下,再在构造方法传入FutureTask:

此时线程就会执行FutureTask内部的Callable中的call方法,计算完成后,就将结果放入FutureTask对象中

FutureTask<V> 泛型参数表示结果的类型

此时在主线程中调用FutureTask中的get()方法(带有阻塞功能),等待计算完毕,从FutureTask中获取到结果

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class Demo {public static void main(String[] args) throws ExecutionException, InterruptedException {Callable<Integer> callable = new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int ret = 0;for (int i = 1; i <= 100; i++) {ret += i;}return ret;}};FutureTask<Integer> futureTask = new FutureTask<>(callable);Thread t = new Thread(futureTask);t.start();//此时无需使用join,使用futureTask中的get()方法获取到结果System.out.println(futureTask.get());}
}

观察两种实现方式,我们可以发现:

使用Callable和FutureTask,使代码简化了很多,且不用使用成员变量来保存结果

Callable和Runnable相对,都是描述一个“任务”,Callable描述的是带有返回值的任务,Runnable描述的是不带返回值的任务

Callable通常需要搭配FutureTask使用,FutureTask用来保存Callable的返回结果

ReentrantLock

ReentrantLock是一种可重入互斥锁,与synchronized类似,都是用来实现互斥效果,保证线程安全的

ReentrantLock的用法:

lock():加锁,若获取不到锁就死等

unlock():解锁

tryLock(超时时间):加锁,若获取不到锁,等待时间一定后就放弃加锁

当我们在使用ReentrantLock时,需要加锁和解锁两个操作,因此当我们在加锁后,很容易忘记解锁,例如在unlock之前,触发了异常 或 return语句,此时就可能不会执行unlock

因此,为了保证unlock的执行,我们可以将其放在finally中

例如:

ReentrantLock lock = new ReentrantLock();
lock.lock();
try{//执行代码
}finally {lock.unlock();
}

synchronzied使用时无需手动释放锁,ReentrantLock使用时需要手动释放,使用起来更加灵活,但也容易漏掉unlock 

为什么有了synchronized后,还有ReentrantLock?


1. ReentrantLock提供了tryLock操作。lock直接进行加锁,当加锁失败时,就阻塞,而tryLock尝试进行加锁,若加锁失败,等待一定时间后,不阻塞,直接放弃加锁,返回 false,表示加锁失败

2. ReentrantLock提供了公平锁的实现(遵循“先来后到”规则,即等待时间长的线程先获取到锁)。通过队列来记录加锁线程的先后顺序,ReentrantLock默认是非公平锁,在构造方法中传入true 则可设置为公平锁

3. 更强大的唤醒机制。synchronized,搭配wait和notify来实现等待唤醒,每次随机唤醒一个等待的线程;而ReentrantLock,搭配Condition类来实现通知等待机制,可以更精确控制唤醒某个指定的线程

Semaphore

信号量Semaphore,用来表示“可用资源的个数”,其本质就是一个计数器

当申请资源时,可用资源数 -1(信号的P操作)

 当释放资源时,可用资源数 +1(信号的V操作)

Semaphore中的加减计算操作都是原子的,可以在多线程环境下直接使用

信号量也是操作系统提供的机制,JVM对其对应的API进行封装,因此我们可用直接通过Java代码来调用这里的相关操作

Semaphore类中acquire()方法表示申请资源(P操作),release()方法表示释放资源(V操作)

例如:

public class Demo2 {public static void main(String[] args) {Semaphore semaphore = new Semaphore(5);//有5个可用资源for (int i = 0; i < 10; i++) {Thread t = new Thread(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();}}});t.start();}}
}

CountDownLatch

同时等待多个任务执行结束

例如,构造CountDownLatch实例latch,初始化n表示有n个任务需要完成。

在任务执行完毕时,调用countDown()方法,告知latch当前任务执行完毕,则CountDownLatch内部的计数器 -1

在主线程中调用latch.await(),阻塞等待所有任务都执行完毕(计数器为0)

import java.util.Random;
import java.util.concurrent.CountDownLatch;public class Demo3 {public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(10);//此时有10个任务需要完成for (int i = 0; i < 10; i++) {int id = i;Thread t = new Thread(()->{Random random = new Random();int time = (random.nextInt(5) + 1) * 1000;//执行任务的时间try {Thread.sleep(time);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(id + "任务执行结束");//告知latch执行结束latch.countDown();});t.start();}//通过await来等待所有任务执行结束latch.await();System.out.println("所有任务都已执行完成");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/629391.shtml

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

相关文章

MySQL实现跨库join查询

MySQL实现跨库join查询 一.同服务器的不同库 只需要在表名前加上db_name select* fromuserdb.user u join orderdb.order o onu.id o.user_id;二.不同服务器的不同库 查看配置 FEDERATED SHOW engines;如果是NO,需要改为YES.默认是NO 在my.ini文件中增加一行&#xff0c;…

Kotlin 进阶

1.lambda 表达式 package com.jmj.myapp.lamdbaimport javax.security.auth.callback.Callbackfun main() {1.test1 {println(this1) }}fun <T> T.test1(callback:T.() -> Unit) {this.callback() }package com.jmj.myapp.lamdbaimport javax.security.auth.callback…

HCIA——11计算机网络分层结构——OSI/ISO、TCP/IP

学习目标&#xff1a; 参考模型 计算机网络 1.掌握计算机网络的基本概念、基本原理和基本方法。 2.掌握计算机网络的体系结构和典型网络协议&#xff0c;了解典型网络设备的组成和特点&#xff0c;理解典型网络设备的工作原理。 3.能够运用计算机网络的基本概念、基本原理和基本…

​​社交媒体与新闻:Facebook在信息传播中的作用

社交媒体已经成为我们获取和传播新闻的主要渠道之一&#xff0c;而Facebook作为社交媒体的巨头&#xff0c;在信息传播中扮演着举足轻重的角色。本文将深入探讨社交媒体对新闻传播的影响&#xff0c;聚焦于Facebook在这一领域的独特作用&#xff0c;以及这种作用对我们的新闻体…

2024华数杯国际赛A题16页完整思路+五小问py代码数据集+后续高质量参考论文

这回带大家体验一下2024“华数杯”国际大学生数学建模竞赛呀&#xff01; 完整内容获取在文末 此题涉及到放射性废水从日本排放到海洋中的扩散问题&#xff0c;以及对环境和人类健康的潜在影响。 ## 问题重述 1. **预测污染范围和程度&#xff1a;** - 使用数学模型描述放射性…

springboot-简单测试 前端上传Excel表格后端解析数据

导入依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxm…

【保姆级教程|YOLOv8添加注意力机制】【2】在C2f结构中添加ShuffleAttention注意力机制并训练

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

Ubantu 安装vscode配置c/c++环境

文章目录 安装VSCode注意 snap包冲突 安装C/C编译环境注意 进程锁占用 配置C开发环境安装插件配置tasks.json配置c_cpp_properties.json 配置调试环境配置 launch.json 安装VSCode 方式一&#xff1a;ubantu 软件里面直接安装 方式二&#xff1a;官网下载deb安装包https://cod…

新增PostgreSQL数据库管理功能,1Panel开源面板v1.9.3发布

2024年1月15日&#xff0c;现代化、开源的Linux服务器运维管理面板1Panel正式发布v1.9.3版本。 在这一版本中&#xff0c;1Panel新增了PostgreSQL数据库管理功能&#xff0c;并且支持设置PHP运行环境扩展模版。此外&#xff0c;我们进行了30多项功能更新和问题修复。1Panel应用…

Android性能优化 | DEX 布局优化和启动配置文件

Android性能优化 | DEX 布局优化和启动配置文件 引言 使用DEX布局优化和启动配置文件是优化Android应用性能的有效途径。DEX布局优化可以通过优化应用程序中的DEX文件布局&#xff0c;从而加快Android应用的启动速度和执行速度。启动配置文件则提供了一种灵活的方式来控制应用…

股票涨跌原理

相信很多人都知道&#xff0c;在每一个价位上成交的多头订单和空头订单的数量都是相等的&#xff0c;那为什么会上涨和下跌&#xff0c;背后的原理是什么&#xff1f; 举个生活中的例子&#xff1a; 其实在交易市场上的成交与我们日常生活中的买卖商品成交是类似的&#xff0…

【杂谈】如何测试EEPROM可以保存数据100年以及擦写次数,磨损均衡问题,阿伦尼乌斯方程的老化测试法

【引出问题】 引用帖子&#xff1a;How Do You Test If An EEPROM Can Hold Data For 100 Years? | Hackaday 在hackaday上看到一篇有意思的帖子&#xff0c;如何测试 EEPROM 是否可以保存数据 100 年以及EERPOM的耐久性问题 比如Microchip的文档里面介绍&#xff0c;EEPRO…

C++I/O流——(4)格式化输入/输出(第一节)

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 含泪播种的人一定能含笑收获&#xff…

独立服务器和云服务器的区别

独立服务器和云服务器的区别是很多用户在选择服务器时要做的课程&#xff0c;那么独立服务器和云服务器的区别有哪些呢? 独立服务器和云服务器是两种不同的服务器部署方式&#xff0c;它们在性能、成本、资源利用、安全性和维护等方面存在显著差异。 1. **性能对比**&#xff…

【DC-6靶场渗透】

文章目录 前言 一、确定靶场地址 二、信息收集 三、账号枚举并破解 四、寻找漏洞 五、反弹shell 六、提权 前言 今天做一下DC6靶场 一、确定靶场地址 1、查看靶机mac地址 2、kali使用nmap&#xff0c;arp-scan工具扫描 nmap -sn 172.16.100.0/24 arp-scan 172.16.100.0/24 I…

Kali Linux保姆级教程|零基础从入门到精通,看完这一篇就够了!(附工具包)

作为一名从事网络安全的技术人员&#xff0c;不懂Kali Linux的话&#xff0c;连脚本小子都算不上。 Kali Linux预装了数百种享誉盛名的渗透工具&#xff0c;使你可以更轻松地测试、破解以及进行与数字取证相关的任何其他工作。 今天给大家分享一套Kali Linux资料合集&#xf…

【大模型评测】常见的大模型评测数据集

开源大模型评测排行榜 https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard 其数据是由其后端lm-evaluation-harness平台提供。 数据集 1.英文测试 MMLU https://paperswithcode.com/dataset/mmlu MMLU&#xff08;大规模多任务语言理解&#xff09…

公网对讲|酒店无线对讲系统

提高工作效率 酒店对讲机可以帮助酒店员工实现快速、有效的内部沟通&#xff0c;从而提高服务质量。例如&#xff0c;前台接待人员可以通过对讲机及时通知客房服务人员为客人提供快速入住服务&#xff0c;或者通知餐饮部门为客人提供送餐服务。此外&#xff0c;对讲机还可以帮…

我劝你千万不要去做CSGO游戏搬砖

大家好&#xff0c;我是阿阳。今天我要给大家讲解一下做CSGO游戏搬砖项目前必须知道的五个问题。作为一个做这个项目已经三年多的老手&#xff0c;我带过的搬砖学员已经有好几百人了。在这个过程中&#xff0c;也积累了不少经验和教训&#xff0c;希望能够通过这篇文章给大家一…

Vue创建项目配置情况

刚开始接触vue项目创建和运行因为node版本和插件版本不一致时长遇到刚装好插件&#xff0c;项目就跑不起来的情况&#xff0c;特此记录一下 vue -V vue/cli 5.0.8 node -v v12.22.12 npm -v 6.14.16 关闭驼峰命名检查、未使用语法检查 package.json文件内容&#xff1a; {&…