【JavaEE】——多线程常用类

 8e19eee2be5648b78d93fbff2488137b.png

阿华代码,不是逆风,就是我疯

你们的点赞收藏是我前进最大的动力!!

希望本文内容能够帮助到你!!

目录

引入:

一:Callable和FutureTask类

1:对比Runnable

2:FutureTask类

3:代码示例

示例一:Runnable

​编辑示例二:Callable

二:ReentrantLock——可重入锁

1:与synchronized的区别

(1)不会阻塞

(2)公平锁

(3)唤醒机制不同

三:Semaphore——信号量

1:P操作

2:V操作

3:PV代码示例一

4:锁功能

四:CountDownLatch

1:引入

2:代码示例


引入:

通过之前的学习,我们了解到CAS本质上是JVM替我们封装好的,我们没有办法感知到

java.util.concurrent中存放了一些我们多线程编程时常用的类

看下面的一些接口:是不是非常熟悉,我们把这个packet包简称为(JUC)

e9ca2cbd045a46b1bbf59c50a57bf57b.png

一:Callable和FutureTask类

读法:“开了波哦”    译为:调用

1:对比Runnable

Runnable提供run方法返回值为void——关注过程,不关注执行结果

Callable提供call方法返回值类型就是执行结果的类型———更关注结果

2:FutureTask类

在Callable中的call方法中完成任务的描述后,我们要想办法把这个任务加载给线程Thread

但是Thread类中并没有给出Callable的构造方法,于是我们通过FutureTask这个中间类(可以理解为加载任务的装置),作为媒介,发射给Thread

即:

Callable中描述方法——卢本伟来啦~~

FutureTask中加载任务——卢本伟已准备就绪~~

Thread中传入futureTask任务执行——卢本伟启动!!

注:

Callable和FutureTask实例化的时候<>中要写返回结果的类型哦。

futureTask.get()方法是带有阻塞功能的,如果线程还没有执行完毕,get就会被阻塞,等到线程执行完了,return的结果就会被get返回回来

3:代码示例

老问题:计算前5000个数字之和
 

看以下两段代码——用Callable类写的代码比Runnable类写的代码更加优雅~~

示例一:Runnable

package thread;public class ThreadDemon37 {private static int sum = 0;//全局变量用来保存最后的结果值public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new Runnable() {int count = 0;//局部变量@Overridepublic void run() {for (int i = 1 ; i <= 5000 ; i++){count += i;}sum = count;}});t1.start();t1.join();System.out.println(sum);}}

c187a3ca91944a6bab8894d443652fed.png示例二:Callable

此处我们不用再引入额外的成员变量了,直接借助返回值即可

package thread;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class ThreadDemon38 {public static void main(String[] args) throws InterruptedException, ExecutionException {Callable<Integer> callable = new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 0; i <= 5000; i++) {sum += i;}return sum;}};//Thread t1 = new Thread(callable);//Thread中没有提供构造函数来传入callable//引入FutureTask类,未来要完成的任务(任务还未执行)// 相当于在Callable中确定执行的任务//在FutureTask装置中完成任务加载——卢本伟准备就绪~~~//最后引入线程——卢本伟启动!!FutureTask<Integer> futureTask = new FutureTask<>(callable);Thread t1 = new Thread(futureTask);t1.start();t1.join();System.out.println(futureTask.get());//装置获得一下结果}
}

f9ffe1814187431eaf22c06ab0cba29c.png

补充一点:.futureTask.get()方法本身自带阻塞特性,如果Callable任务还没有执行完,是会一直等待它的返回值结果的

二:ReentrantLock——可重入锁

读音:“瑞安纯特老科” 翻译为:可重入锁

科普:ReentrantLock在很早以前是比没有发展起来的synchronized功能更加强大的,他提供了两个传统的方法lock和unlock,但是在写代码的过程中lock完后往往会忘记unlock解锁,所以一般把unlock操作放到finally里面使用

1:与synchronized的区别

(1)不会阻塞

我们知道synchronized加锁,如果线程“锁竞争”失败,会陷入阻塞等待,使用了ReentrantLodk提供了trylock方法后,如果加不上锁就会返回false,不会阻塞等待。

(2)公平锁

ReentrantLock中加锁依据是:公平锁,所有参与“加锁”的线程会被放进队列里面,按顺序进行加锁

(3)唤醒机制不同

synchronized提供wait和notify,ReentrantLock搭配Condition,功能比notify强一点

三:Semaphore——信号量

读音:“赛摸佛尔” 翻译为:信号量

科普:因为发明信号量的大佬迪杰斯特拉是个荷兰人,荷兰语的申请和释放首字母分别是P和V。实际上英语是acquire和release

1:P操作

申请一个可用资源,可用资源总数就会-1

2:V操作

释放一个可用资源,可用资源总数就会+1

打个比方:去停车场停车,现在有50个停车位,申请一个停车位(p操作),现有可用停车位为49;出来了一辆车(v操作),现有可用停车位为50;

3:PV代码示例一

package thread;import java.util.concurrent.Semaphore;/*** Created with IntelliJ IDEA.* Description:* User: Hua YY* Date: 2024-09-30* Time: 10:26*/
public class ThreadDemon39 {public static void main(String[] args) throws InterruptedException {Semaphore semaphore = new Semaphore(1);//资源数限制为1个semaphore.acquire();System.out.println("p操作");semaphore.acquire();//第二次申请System.out.println("p操作");semaphore.acquire();//第三次申请System.out.println("p操作");}
}

9cf9b627497042ea9426d8388842301a.png

4:锁功能

信号量是更为广义的锁

代码示例:继续沿用解决count计数器++线程安全问题的方式

package thread;import java.util.concurrent.Semaphore;/*** Created with IntelliJ IDEA.* Description:* User: Hua YY* Date: 2024-09-30* Time: 10:33*/
public class ThreadDemon40 {private static int count = 0;//引入Semaphore进行加锁private static Semaphore semaphore = new Semaphore(1);public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {try {semaphore.acquire();//加锁for (int i = 1 ; i <= 50000 ; i++){count++;}} catch (InterruptedException e) {throw new RuntimeException(e);}semaphore.release();//解锁});Thread t2 = new Thread(() ->{try {semaphore.acquire();//加锁for (int i = 1 ; i <= 50000 ; i++){count++;}} catch (InterruptedException e) {throw new RuntimeException(e);}semaphore.release();//解锁});t1.start();t2.start();t1.join();t2.join();System.out.println(count);}
}

4f2381686367498d83b6d9736d662e7c.png

四:CountDownLatch

1:引入

latch(锁存器)

举个例子,现在下载软件的速度非常快,用的是多线程下载方式,比如要下载一个1G大小的软件,我们把这个任务分成10份,分给10个线程同时进行下载,最后在拼在一起,速度就会快非常多。

这个“拼”的操作,就能被CountDownLatch感知到,比我们用join要更简单方便一些

2:代码示例

package thread;import java.util.Random;
import java.util.concurrent.CountDownLatch;/*** Created with IntelliJ IDEA.* Description:* User: Hua YY* Date: 2024-09-30* Time: 10:57*/
public class ThreadDemon41 {public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(10);//创建10个线程Random random = new Random();int time = (random.nextInt(4)+1)*1000;//time的范围[0,4]->[1,5]->[1000,5000]for(int i = 1 ; i <= 10 ; i++){int count = i;Thread t = new Thread(() ->{try {Thread.sleep(random.nextInt(time));//产生的随机数的范围System.out.println("第" + count + "线程的任务执行完毕");latch.countDown();//告知CountDownLatch有一个任务已经执行完毕了} catch (InterruptedException e) {throw new RuntimeException(e);}});t.start();}latch.await();//如果CountDownLatch中的任务还没有执行完毕,那么CountDownLatch就会陷入阻塞等待System.out.println("所有任务都已经执行完毕了");}
}

ab344df1b057467297751a6554e614ea.png

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

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

相关文章

动手学深度学习-GPU常见报错-CUDA11.4-AssertionError: Torch not compiled with CUDA enabled

目录 本文还能解决&#xff1a; 0. 问题原因 1. 查看机器的cuda版本 2. 从官网下载对应的torch和torchvision 3. 具体安装方法 本文还能解决&#xff1a; torch.cuda.is_available() 输出为 False&#xff1b; torch.cuda.device_count() 输出为 0 0. 问题原因 这两个问题…

【C++笔记】初始模版和STL简介

【C笔记】初始模版和STL简介 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】初始模版和STL简介前言一.初始模版1.1泛型编程1.2函数模版1.3类模板 二.STL简介2.1什么是STL2.2STL的版本2.3STL的六大组件2.4STL的重要…

【C++并发入门】opencv摄像头帧率计算和多线程相机读取(下):完整代码实现

前言 高帧率摄像头往往应用在很多opencv项目中&#xff0c;今天就来通过简单计算摄像头帧率&#xff0c;抛出一个单线程读取摄像头会遇到的问题&#xff0c;同时提出一种解决方案&#xff0c;使用多线程对摄像头进行读取。上一期&#xff1a;【C并发入门】摄像头帧率计算和多线…

RDI ADCP命令与ASCII输出结构

RDI ADCP命令与ASCII输出结构 一、RDI垂直式ADCP:1.1固定命令&#xff1a;1.2 向导命令 二、RDI水平式ADCP三、ADCP 公共目录四、常用BBTalk命令五、ADCP的ASCII输出数据文件、流量与数据结构5.1 ASCII类输出&#xff1a;5.2 ASCII 输出数据文件头5.3 ASCII 输出数据集5.4 导航…

Llama 3.2来了,多模态且开源!AR眼镜黄仁勋首批体验,Quest 3S头显价格低到离谱

如果说 OpenAI 的 ChatGPT 拉开了「百模大战」的序幕&#xff0c;那 Meta 的 Ray-Ban Meta 智能眼镜无疑是触发「百镜大战」的导火索。自去年 9 月在 Meta Connect 2023 开发者大会上首次亮相&#xff0c;短短数月&#xff0c;Ray-Ban Meta 就突破百万销量&#xff0c;不仅让马…

位运算(6)_只出现一次的数字 II

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 位运算(6)_只出现一次的数字 II 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 …

psutil库的使用说明

前言 psutil是一个跨平台的库&#xff0c;用于获取系统的进程和系统利用率&#xff08;包括 CPU、内存、磁盘、网络等&#xff09;信息。 目录 安装 应用场景 常用方法 一、系统信息相关函数 二、进程信息相关函数 三、网络信息相关函数 四、其他实用函数 使用样例 监控应…

Could not find com.mapbox.mapboxsdk:mapbox-android-accounts:0.7.0.解决

AndroidStudio编译APK出现如下错误&#xff1a; Could not find com.mapbox.mapboxsdk:mapbox-android-accounts:0.7.0. 出现上面错误原因是因为没有打开对应的仓库导致的&#xff0c; 手动添加如下创建地址可解决&#xff1a; maven { url https://maven.aliyun.com/repos…

Windows远程Kylin系统-xrdp

Windows远程Kylin系统-xrdp 一. 查看开放端口 查看是否有3389端口二. 安装xrdp Kylin对应的是centos8 下载链接&#xff1a;https://rhel.pkgs.org/8/epel-x86_64/xrdp-0.10.1-1.el8.x86_64.rpm.html rpm -Uvh 包名 systemctl start xrdp 启动服务 systemctl enable xrdp …

【HTML5】html5开篇基础(4)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

解决问题AttributeError: “safe_load“ has been removed, use

解决问题AttributeError: "safe_load" has been removed, use~ 1. 问题描述2. 解决方法 1. 问题描述 在复现cdvae代码时&#xff0c;运行 python scripts/compute_metrics.py --root_path MODEL_PATH --tasks recon gen opt评估模型时&#xff0c;出现以下问题。 …

Python批量下载PPT模块并实现自动解压

日常工作中&#xff0c;我们总是找不到合适的PPT模板而烦恼。即使有免费的网站可以下载&#xff0c;但是一个一个地去下载&#xff0c;然后再批量解压进行查看也非常的麻烦&#xff0c;有没有更好方法呢&#xff1f; 今天&#xff0c;我们利用Python来爬取一个网站上的PPT&…

【ios】---swift开发从入门到放弃

swift开发从入门到放弃 环境swift入门变量与常量类型安全和类型推断print函数字符串整数双精度布尔运算符数组集合set字典区间元祖可选类型循环语句条件语句switch语句函数枚举类型闭包数组方法结构体 环境 1.在App Store下载Xcode 2.新建项目&#xff08;可以先使用这个&…

Hadoop HDFS命令操作实例

一.创建与查看HDFS目录 每次重启后&#xff0c;Jps和java -version执行出来的结果不符合就使用 source ~/.bash_profile 是在 Unix/Linux 系统上用来重新加载用户的 Bash 配置文件 ~/.bash_profile 的命令。这条命令的作用是使得当前的 Bash 环境重新读取并应用 ~/.bash_pro…

PHP安装后Apache无法运行的问题

问题 按照网上教程php安装点击跳转教程&#xff0c;然后修改Apache的httpd.conf文件&#xff0c;本来可以运行的Apache&#xff0c;无法运行了 然后在"C:\httpd-2.4.62-240904-win64-VS17\Apache24\logs\error.log"&#xff08;就是我下载Apache的目录下的logs中&am…

当AI成为作家,人工智能在写作领域的崛起

AI写作技术的应用正在多个领域展现出其强大的潜力和价值&#xff0c;它不仅极大地提升了内容创作的效率&#xff0c;还为创作者提供了一个全新的创作伙伴。 随着技术的进步&#xff0c;AI写作工具越来越能够理解复杂的语境和用户需求&#xff0c;帮助创作者生成高质量的内容。…

排水系统C++

题目&#xff1a; 样例解释&#xff1a; 1 号结点是接收口&#xff0c;4,5 号结点没有排出管道&#xff0c;因此是最终排水口。 1 吨污水流入 1 号结点后&#xff0c;均等地流向 2,3,5 号结点&#xff0c;三个结点各流入 1/3 吨污水。 2 号结点流入的 1/3​ 吨污水将均等地流向…

深度学习与数学归纳法

最近发现&#xff0c;深度学习可以分为两个主要的阶段&#xff0c;分别是前向推理以及反向传播&#xff0c;分别对应着网络的推理和参数训练两个步骤。其中推理有时候也称为归纳推理。 在做参数训练的时候&#xff0c;本质上是在利用历史数据求网络参数的先验分布&#xff1b; …

Java 基础语法 Day10

一、异常 1.1异常的基本处理 1.抛出异常&#xff1a;throw 2.捕获异常&#xff1a;try-catch 1.2异常的作用 1.定位程序bug的关键信息 2.可以作为方法内部的一种特殊返回值&#xff0c;通知给上层调用&#xff0c;方便处理 //需求&#xff1a;将两个数的除返回 public cla…

音视频入门基础:FLV专题(9)——Script Tag简介

一、SCRIPTDATA 根据《video_file_format_spec_v10_1.pdf》第75页到76页&#xff0c;如果某个Tag的Tag header中的TagType值为18&#xff0c;表示该Tag为Script Tag&#xff08;脚本Tag&#xff0c;又称Data Tag、SCRIPTDATA tag&#xff09;。这时如果Filter的值不为1表示未加…