2023年Java核心技术第十一篇(篇篇万字精讲)

目录

二十一 . Java并发包提供了哪些并发工具类

21.1 典型回答

21.1 .1  CountDownLatch

21.1 .2  CyclicBarrier

21.1 .2.1 例子:

21.1 .2.2  输出结果:

21.1.2.3 详细解释:屏障点

21.1.3  Semaphore

21.1.3.1 使用 Semaphore例子:

21.1.3.2 输出结果:

21.1.3.3 安全容器和队列

21.1.3.4 Executor框架


二十一 . Java并发包提供了哪些并发工具类

 在前面的篇幅中我们进行了,线程,锁,等并发编程的基础元素的讲解。

21.1 典型回答


我们通常所说的并发包也就是 java.util.concurrent 及其子包,集中了 Java 并发的各种基础
工具类。

具体主要包括几个方面:
提供了比 synchronized 更加高级的各种同步结构,包括 CountDownLatch、
CyclicBarrier、Semaphore 等,可以实现更加丰富的多线程操作,比如利用Semap作为资源控制器,限制同时进行工作的线程数量。

21.1 .1  CountDownLatch

创建一个CountDownLatch对象,并将其计数器初始化为3:

CountDownLatch countDownLatch = new CountDownLatch(3);

 创建一个InterfaceRequestThread类,继承自Thread类,用于发起接口请求并倒计时:

public class InterfaceRequestThread extends Thread {private final CountDownLatch countDownLatch;public InterfaceRequestThread(CountDownLatch countDownLatch) {this.countDownLatch = countDownLatch;}@Overridepublic void run() {// 发起接口请求操作System.out.println("请求接口数据...");try {Thread.sleep(2000); // 模拟接口请求耗时} catch (InterruptedException e) {e.printStackTrace();}System.out.println("接口数据请求完成。");countDownLatch.countDown(); // 计数器减一}
}

 主线程中创建多个InterfaceRequestThread线程,并启动它们:

// 创建CountDownLatch对象
CountDownLatch countDownLatch = new CountDownLatch(3);// 创建三个InterfaceRequestThread线程,并启动它们
for (int i = 0; i < 3; i++) {Thread thread = new InterfaceRequestThread(countDownLatch);thread.start();
}

在主线程中调用await()方法等待计数器达到零,然后进行下一步处理:

try {countDownLatch.await(); // 等待计数器达到零System.out.println("所有接口数据请求完成,开始进行下一步处理...");// 进行下一步操作,例如数据处理等
} catch (InterruptedException e) {e.printStackTrace();
}

 运行时,会观察到每个InterfaceRequestThread线程都会发起接口请求,并在请求完成后将CountDownLatch的计数器减一。当所有线程的请求都完成后,主线程就会从await()方法中返回,并输出"所有接口数据请求完成,开始进行下一步处理...",表示可以开始下一步操作了。

通过CountDownLatch,我们实现了多个线程之间的协作与同步,确保所有接口数据都请求完毕后再进行下一步操作。这在需要等待其他线程完成某项操作后再继续执行的场景中非常有用。

21.1 .2  CyclicBarrier

CyclicBarrier 是 Java 提供的一种同步工具类,它可以用于多个线程之间相互等待,直到所有线程都达到一个共同的屏障点,然后同时继续执行。

CyclicBarrier 的主要特点如下:

  • 它可以接收一个整数作为构造函数参数,该整数表示需要等待的线程数量。
  • 每个线程在达到屏障点时会调用 await() 方法,此时该线程会被阻塞,直到所有线程都调用了 await() 方法。
  • 当所有线程都调用了 await() 方法后,所有线程会同时被释放,可以继续执行后续操作。
  • CyclicBarrier 的计数器可以重置,因此它可以被重复使用。

21.1 .2.1 例子:

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;public class CyclicBarrierExample {public static void main(String[] args) {int numberOfThreads = 3;Runnable barrierAction = () -> System.out.println("All threads have reached the barrier");CyclicBarrier barrier = new CyclicBarrier(numberOfThreads, barrierAction);for (int i = 0; i < numberOfThreads; i++) {Thread thread = new Thread(new Worker(barrier));thread.start();}}static class Worker implements Runnable {private final CyclicBarrier barrier;Worker(CyclicBarrier barrier) {this.barrier = barrier;}@Overridepublic void run() {try {System.out.println("Thread started");// 模拟线程的工作Thread.sleep(1000);System.out.println("Thread finished work and waiting at the barrier");barrier.await();System.out.println("Thread released from the barrier and continuing its work");} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}}
}

21.1 .2.2  输出结果:

Thread started
Thread finished work and waiting at the barrier
Thread started
Thread finished work and waiting at the barrier
Thread started
Thread finished work and waiting at the barrier
All threads have reached the barrier
Thread released from the barrier and continuing its work
Thread released from the barrier and continuing its work
Thread released from the barrier and continuing its work

我们创建了一个 CyclicBarrier 对象,并指定等待的线程数量为 3,同时传入一个 barrierAction,当所有线程都达到屏障点时,会执行该 barrierAction

每个线程在 run() 方法中模拟一些工作,并调用 await() 方法等待其他线程。当所有线程都调用了 await() 方法后,它们会同时被释放,继续执行后续操作。

在输出结果中,可以看到三个线程同时执行到了屏障点,并输出了 "All threads have reached the barrier" 的信息,然后它们继续执行剩余的工作。

通过使用 CyclicBarrier,可以实现多个线程之间的同步,让它们在某个点上进行协调,等待彼此达到同一个状态,然后再继续执行后续操作。这在需要线程间相互等待的场景下非常有用,例如并行计算中将计算结果合并,多个线程同时开始某个任务等等。

21.1.2.3 详细解释:屏障点

屏障点是CyclicBarrier对象的构造函数中指定的等待线程数量达到了设定值。也就是说,当3个线程都调用了await()方法后,它们会在CyclicBarrier对象的屏障点处等待。

具体来说,在该例子中,CyclicBarrier对象的构造函数参数为3,表示需要等待3个线程。当第一个线程调用await()方法时,它会被阻塞,直到所有3个线程都调用了await()方法。当第二个和第三个线程都调用了await()方法后,所有线程都达到了屏障点并等待。

一旦所有线程都达到屏障点,屏障点就会打开,所有线程都会被释放并继续执行后续操作。

21.1.3  Semaphore

Semaphore(信号量)是一种并发控制机制,用于限制同时访问某个共享资源的线程数量。它可以用于控制对临界区的访问,或者限制对有限资源的并发访问。

Semaphore 主要有两个操作:acquire()release()

  • acquire(): 当一个线程需要访问被 Semaphore 保护的资源时,它调用 acquire() 方法进行获取信号量。如果信号量计数器大于0,该线程可以继续执行,同时信号量计数器减1。如果信号量计数器为0,那么该线程将被阻塞,直到有其他线程调用 release() 方法释放信号量。
  • release(): 当一个线程访问完被 Semaphore 保护的资源后,它调用 release() 方法释放信号量。该操作会使信号量计数器增加1,并且唤醒一个或多个被阻塞的线程,允许它们继续执行。

Semaphore 的计数器可以初始化为一个非负整数。如果计数器初始化为1,那么 Semaphore 就变成了互斥锁的功能,也被称为二元信号量。

21.1.3.1 使用 Semaphore例子:

import java.util.concurrent.Semaphore;public class SemaphoreExample {public static void main(String[] args) {int numberOfPermits = 3; // 允许同时访问资源的线程数量Semaphore semaphore = new Semaphore(numberOfPermits);for (int i = 0; i < 5; i++) {Thread thread = new Thread(new Worker(semaphore));thread.start();}}static class Worker implements Runnable {private final Semaphore semaphore;Worker(Semaphore semaphore) {this.semaphore = semaphore;}@Overridepublic void run() {try {System.out.println("Thread acquiring semaphore");semaphore.acquire();System.out.println("Thread acquired semaphore and performing its task");Thread.sleep(2000);System.out.println("Thread released semaphore");semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}}}
}

21.1.3.2 输出结果:

Thread acquiring semaphore
Thread acquiring semaphore
Thread acquiring semaphore
Thread acquired semaphore and performing its task
Thread acquired semaphore and performing its task
Thread acquired semaphore and performing its task
Thread releasing semaphore
Thread releasing semaphore
Thread releasing semaphore

我们创建了一个 Semaphore 对象,并指定允许同时访问资源的线程数量为3。然后,我们创建了5个线程,并在每个线程中进行一些任务。

每个线程在运行时首先调用 acquire() 方法来获取信号量。如果有可用的许可证(计数器大于0),线程将继续执行,并且信号量计数器减1。如果没有可用的许可证(计数器为0),线程将被阻塞,直到有其他线程释放信号量。

在线程执行完任务后,它调用 release() 方法来释放信号量,使得其他等待的线程能够继续执行。

需要注意的是,在获取和释放信号量时要确保正确使用,以免导致死锁或访问冲突的问题。因此,在编写使用 Semaphore 的程序时,需要仔细设计和管理信号量的获取和释放操作,以确保线程间的正确协调和资源的正确使用。

21.1.3.3 安全容器和队列

各种线程安全的容器,比如常见的ConcurrentHashMap,有序的ConcurrentSkipListMap,或者通过类似快照机制,实现线程安全的动态数组CopyOnWriteArrayList。

以及并发队列实现,如:BlockingQueue实现,比较典型的ArrayBlockingQueue,SynchronousQueue或对特定场景的PriorityBlockingQueue等这些在前面的篇幅中有详细解释。

21.1.3.4 Executor框架

强大的Executor框架,可以创建各种不同类型的线程池,调度任务运行等,绝大部分情况,不需要自己从头进行实现线程池和任务调度器。

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

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

相关文章

ros::NodeHandle用途用法

在ROS(Robot Operating System)中,ros::NodeHandle 是一个核心类,用于与ROS系统进行交互。几乎所有的ROS节点功能,例如发布或订阅主题、调用或提供服务,都需要使用到 ros::NodeHandle。 用途: 与ROS系统交互:ros::NodeHandle 是节点与ROS计算图系统进行通讯的主要接口…

GCC和G++的区别

GCC和G是我们在学习C/C并且进行编译的过程中&#xff0c;必会的知识点&#xff0c;今天小雷雷针对这个聊几句&#xff0c;嗯哼哼~ &#x1f449;&#x1f449;&#x1f449;gcc和g都是C/C的编译器&#xff0c;但是它们之间存在一些区别 GCC和G的渊源 GCC&#xff08;GNU Comp…

【C语言进阶(10)】通讯录管理系统

文章目录 Ⅰ 系统功能介绍Ⅱ 系统前期准备⒈菜单功能⒉结构体设计⒊通讯录初始化 Ⅲ 系统功能实现⒈添加联系人⒉删除联系人⒊查找联系人⒋修改联系人⒌显示联系人⒍排序联系人⒎清空联系人 Ⅳ 完整代码展示⒈test.c⒉contact.h⒊contact.c Ⅰ 系统功能介绍 系统中需要实现的功…

matlab 计算点云协方差矩阵

目录 一、概述1、算法概述2、主要函数二、代码示例三、结果展示四、参数解析输入参数输出参数五、参考链接本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、概述

java 可变参数

基本语法 可变参数的语法很简单&#xff0c;基本格式如下&#xff1a; 方法名(参数类型 ...)举例 public void printName(String... names) {int count names.length;for (int i 0; i < names.length; i) {System.out.println(names[i]);} }

气传导蓝牙耳机好不好?推荐几款不错的气传导耳机

​在众多的气传导耳机中&#xff0c;如何选择一款适合自己的气传导耳机呢&#xff1f;这需要考虑到自己的需求和预算&#xff0c;同时也需要了解不同品牌和型号的产品特点和优缺点。下面我来推荐几款非常不错的气传导耳机给大家参考&#xff0c;希望大家都能寻找到心仪那款。 …

【线性代数】矩阵求导的本质与分子布局、分母布局的本质(矩阵求导——本质篇)

矩阵求导的本质与分子布局、分母布局的本质&#xff08;矩阵求导——本质篇&#xff09; 说在前面一. 函数与标量、向量、矩阵二. 矩阵求导的本质三. 矩阵求导结果的布局四. 分子布局、分母布局的本质五. 向量变元的实值标量函数 说在前面 我将严谨地说明矩阵求导的本质与分子布…

centos下配置SFTP且限制用户访问目录

一、SFTP使用场景 ftp是大多数网站的文件传输选择工具,但ftp并不是非常安全,并且在centos上搭建的vsftpd也非常的不稳定,偶尔会出现权限问题,例如500、或是账号密码不正确等等。 而SFTP是基于默认的22端口,是ssh内含的协议,只要启动了sshd就可以使用。 建议:更高的效率…

[ES]mac安装es、kibana、ik分词器

一、安装es和kibana 1、创建一个网络&#xff0c;网络内的框架(eskibana)互联 docker network create es-net 2、下载es和kibana docker pull elasticsearch:7.12.1 docker pull kibana:7.12.1 3、运行docker命令部署单点eskibana&#xff08;用来操作es&#xff09; doc…

leetcode分类刷题:字符串及单词翻转

1、本文此次总结的题型“leetcode分类刷题&#xff1a;字符串及单词翻转”较为简单&#xff0c;是双指针法在字符串及单词翻转类题型中的应用 2、如果单词翻转类题型加了O(1)空间复杂度的要求&#xff0c;算法思路会变得稍微复杂一点 344. 反转字符串 该题为字符串翻转的基础题…

ConsoleApplication17_2项目免杀(Fiber+VEH Hook Load)

加载方式FiberVEH Hook Load Fiber是纤程免杀&#xff0c;VEH是异常报错&#xff0c;hook使用detours来hook VirtualAlloc和sleep&#xff0c;通过异常报错调用实现主动hook 纤程Fiber的概念&#xff1a;纤程是比线程的更小的一个运行单位。可以把一个线程拆分成多个纤程&#…

InVEST模型+SolVES模型教程

详情点击公众号链接&#xff1a;基于当量因子法、InVEST、SolVES模型等多技术融合在生态系统服务功能社会价值评估中的应用及论文写作、拓展分析 前言 生态系统服务是人类从自然界中获得的直接或间接惠益&#xff0c;可分为供给服务、文化服务、调节服务和支持服务4类&#xf…

基于Ubuntu坏境下的Suricata坏境搭建

目录 Suricata环境安装 第一步、在 Ubuntu 端点安装 Suricata 1、加入Suricata源 2、更新安装包 3、下载SuricataSuricata 第二步、下载并提取新兴威胁 Suricata 规则集 1、在tmp文件夹下载 Suricata 规则集 如果发现未安装curl&#xff0c;使用apt安装即可&#xff1a…

打造高权重店铺的秘密,详解Shopee平台权重评估机制(测评补单)

很多虾皮卖家经常提到的"权重"是指商品或店铺在Shopee平台上的重要性程度。权重评估了商品或店铺是否符合用户需求&#xff0c;并且能否促进订单转化率&#xff0c;为平台带来收益。说白了权重就是给商品和店铺打分的机制&#xff0c;得分越高&#xff0c;权重越高&a…

简单shell脚本的编写

文章目录 简单使用shell脚本参数判断整数的比较运算符字符串的比较运算shell脚本流程控制shell脚本循环for循环批量添加用户批量ping IP地址检测同一局域网&#xff0c;多台主机存活情况检测同一局域网&#xff0c;多台主机存活情况多线程检测主机存活情况 while循环case选择语…

Python中处理Excel文件的常见问题与技巧

在数据分析和办公自动化领域&#xff0c;Excel是一种广泛使用的工具。本文将介绍如何利用Python来处理Excel文件时可能遇到的常见问题&#xff0c;并分享一些实用技巧。 1. 安装必要库 - 使用pip或conda安装openpyxl、pandas等第三方库&#xff1b; – 确保所选版本兼容性以及…

Java之SpringCloud Alibaba【五】【微服务 Sentinel整合openfeign进行降级】

一、Sentinel整合openfeign 1、复制一下order-openfeign项目&#xff08;创建order-openfeign-sentinel&#xff09; 然后在stock-nacos当中编写对应的接口 RequestMapping("/reduct2")public String reduct2(){int a 1/0;System.out.println("扣减库存"…

单片机学习-什么是Flash?什么是RAM?什么是ROM?

什么是Flash&#xff1f; Flash 存储器&#xff08;FLASH EEPROM&#xff09;又称闪存&#xff0c;快闪。 它是EEPROM的一种。它结合了ROM和RAM的长处。不仅具备电子可擦除可编辑&#xff08;EEPROM&#xff09;的性能&#xff0c;还不会断电丢失数据同时可以快速读取数据。它于…

说说Lambda架构

分析&回答 Lambda架构是由Storm的作者Nathan Marz提出的一个实时大数据处理框架。Marz在Twitter工作期间开发了著名的实时大数据处理框架Storm&#xff0c;Lambda架构是其根据多年进行分布式大数据系统的经验总结提炼而成。Lambda架构的目标是设计出一个能满足实时大数据系…

python读取图像小工具

一、和图像交互获得图像的坐标和像素值 import cv2 import numpy as np import signal import threading import timeif __name__ __main__:img cv2.imread(XXX,0)#读取图片font_face,font_scale,thicknesscv2.FONT_HERSHEY_SIMPLEX,0.5,1#鼠标交互def mouseHandler(event,x…