【面试】Java最新面试题资深开发-Java中的并发集合类

问题五:Java中的并发集合类

Java提供了许多并发集合类来处理多线程环境下的数据共享和同步。你能列举一些Java中常用的并发集合类,并简要说明它们的特点和使用场景吗?

以下六个是经常被使用的,它们在实际开发中发挥着重要作用:

  1. ConcurrentHashMap:

    • 特点: 高并发安全,采用分段锁机制,适用于高并发的读写操作。
    • 使用场景: 频繁读写的数据缓存,需要高并发性能的场景。
  2. CopyOnWriteArrayList:

    • 特点: 写时复制,适用于读操作频繁、写操作较少的场景。
    • 使用场景: 事件监听器列表等读多写少的场合。
  3. BlockingQueue:

    • 特点: 阻塞队列,用于实现线程之间的数据传递和同步。
    • 使用场景: 生产者-消费者模型,任务调度等。
  4. Semaphore:

    • 特点: 信号量,用于控制同时访问特定资源的线程数量。
    • 使用场景: 资源池的控制,控制并发访问的线程数量。
  5. CountDownLatch:

    • 特点: 倒计数器,用于等待多个线程完成任务后再执行后续操作。
    • 使用场景: 主线程等待多个子线程完成后再执行的场景。
  6. CyclicBarrier:

    • 特点: 循环屏障,多个线程互相等待,当所有线程都达到某个状态后,同时执行后续操作。
    • 使用场景: 多个线程协同工作,等待其他线程到达某个状态后再继续执行的场景。

下面,我将对每个类进行更详细的讲解,并提供一些示例代码来说明它们的用法。由于篇幅限制,每个类的讲解将简洁明了,着重强调关键概念和用法。

1. ConcurrentHashMap

特点:

  • 高并发安全: 使用分段锁机制,每个段相当于一个小的HashTable,不同段之间互相独立,提高了并发读的性能。
  • 读操作不加锁: 在读操作上不加锁,多个线程可以同时读取,提高了并发读的效率。
  • 动态扩容: 允许在并发的情况下进行扩容操作。

使用场景:

  • 适用于高并发的读写操作,例如在多线程环境下频繁读写的数据缓存。

示例代码:

import java.util.concurrent.ConcurrentHashMap;public class ConcurrentHashMapExample {public static void main(String[] args) {ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();// 线程安全的put操作concurrentMap.put("A", 1);concurrentMap.put("B", 2);// 线程安全的get操作int valueA = concurrentMap.get("A");int valueB = concurrentMap.get("B");System.out.println("Value for A: " + valueA);System.out.println("Value for B: " + valueB);}
}

在这个示例中,ConcurrentHashMap 提供了线程安全的 putget 操作,无需额外的同步手段,适用于高并发的场景。
在这里插入图片描述

2. CopyOnWriteArrayList

特点:

  • 写时复制: 写操作时,先复制整个列表,进行修改,然后将新的列表替换原来的列表。
  • 读操作无锁: 读操作不需要加锁,可以被多个线程同时执行。
  • 适用于读多写少: 适用于对列表的读操作比写操作频繁的场景。

使用场景:

  • 适用于读操作频繁,写操作较少的场景,例如事件监听器列表。

示例代码:

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;public class CopyOnWriteArrayListExample {public static void main(String[] args) {List<String> copyOnWriteList = new CopyOnWriteArrayList<>();// 线程安全的添加操作copyOnWriteList.add("A");copyOnWriteList.add("B");// 线程安全的遍历操作for (String item : copyOnWriteList) {System.out.println("Item: " + item);}}
}

在这个示例中,CopyOnWriteArrayList 提供了线程安全的列表,通过写时复制机制保证了在读多写少的场景中的高效性。

接下来,我们将继续探讨 BlockingQueue

3. BlockingQueue

特点:

  • 阻塞队列: 提供了在队列为空或队列已满时阻塞线程的功能。
  • 线程安全: 内部实现了线程安全的操作,适用于多线程间的数据传递和同步。
  • 多种实现: Java提供了多种阻塞队列的实现,如ArrayBlockingQueueLinkedBlockingQueue等。

使用场景:

  • 适用于多线程数据传递和同步的场景,例如生产者-消费者模型,任务调度等。

示例代码:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;public class BlockingQueueExample {public static void main(String[] args) {BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3); // 定义容量为3的阻塞队列// 生产者线程new Thread(() -> {try {blockingQueue.put("A"); // 阻塞式地添加元素System.out.println("Produced item A");blockingQueue.put("B");System.out.println("Produced item B");} catch (InterruptedException e) {e.printStackTrace();}}).start();// 消费者线程new Thread(() -> {try {String item = blockingQueue.take(); // 阻塞式地获取元素System.out.println("Consumed item: " + item);item = blockingQueue.take();System.out.println("Consumed item: " + item);} catch (InterruptedException e) {e.printStackTrace();}}).start();}
}

在这个示例中,BlockingQueue 通过 puttake 操作提供了阻塞式的添加和获取元素的功能,适用于生产者-消费者模型。

4. Semaphore

特点:

  • 信号量: 用于控制同时访问特定资源的线程数量。
  • 计数信号量: 通过计数进行控制,每次访问资源时减少计数,释放资源时增加计数。

使用场景:

  • 适用于控制资源访问的并发场景,如连接池的控制,限制最大并发访问数。

示例代码:

import java.util.concurrent.Semaphore;public class SemaphoreExample {public static void main(String[] args) {Semaphore semaphore = new Semaphore(2); // 允许两个线程同时访问资源// 线程1new Thread(() -> {try {semaphore.acquire(); // 尝试获取资源System.out.println("Thread 1 acquired the resource.");Thread.sleep(2000); // 模拟工作时间semaphore.release(); // 释放资源System.out.println("Thread 1 released the resource.");} catch (InterruptedException e) {e.printStackTrace();}}).start();// 线程2new Thread(() -> {try {semaphore.acquire(); // 尝试获取资源System.out.println("Thread 2 acquired the resource.");Thread.sleep(2000); // 模拟工作时间semaphore.release(); // 释放资源System.out.println("Thread 2 released the resource.");} catch (InterruptedException e) {e.printStackTrace();}}).start();}
}

在这个示例中,Semaphore 通过 acquirerelease 操作提供了对资源的控制,限制了同时访问资源的线程数量。

接下来,我们将继续学习 CountDownLatch

5. CountDownLatch

特点:

  • 倒计数器: 用于等待多个线程完成任务后,再执行后续操作。
  • 计数减少: 初始设定一个计数值,每个线程完成任务时,将计数减一,直到计数为零。

使用场景:

  • 适用于主线程等待多个子线程完成后再执行的场景。

示例代码:

import java.util.concurrent.CountDownLatch;public class CountDownLatchExample {public static void main(String[] args) {CountDownLatch countDownLatch = new CountDownLatch(2); // 两个子线程完成任务后,主线程才能执行// 子线程1new Thread(() -> {System.out.println("Thread 1 is doing some work.");countDownLatch.countDown(); // 任务完成,计数减一}).start();// 子线程2new Thread(() -> {System.out.println("Thread 2 is doing some work.");countDownLatch.countDown(); // 任务完成,计数减一}).start();try {// 主线程等待计数归零countDownLatch.await();System.out.println("All threads have completed their tasks. Main thread is now executing.");} catch (InterruptedException e) {e.printStackTrace();}}
}

在这个示例中,CountDownLatch 通过 countDownawait 操作提供了等待多个线程完成任务的功能。主线程等待计数归零后再执行。

6. CyclicBarrier

特点:

  • 循环屏障: 多个线程互相等待,当所有线程都达到某个状态后,同时执行后续操作。
  • 可循环使用: 在所有线程到达屏障后,可以重置屏障,继续使用。

使用场景:

  • 适用于多个线程协同工作,等待其他线程到达某个状态后再继续执行的场景。

示例代码:

import java.util.concurrent.CyclicBarrier;public class CyclicBarrierExample {public static void main(String[] args) {CyclicBarrier cyclicBarrier = new CyclicBarrier(3); // 三个线程到达屏障后,同时执行// 线程1new Thread(() -> {System.out.println("Thread 1 is ready.");try {cyclicBarrier.await(); // 等待其他线程到达System.out.println("Thread 1 is executing.");} catch (Exception e) {e.printStackTrace();}}).start();// 线程2new Thread(() -> {System.out.println("Thread 2 is ready.");try {cyclicBarrier.await(); // 等待其他线程到达System.out.println("Thread 2 is executing.");} catch (Exception e) {e.printStackTrace();}}).start();// 线程3new Thread(() -> {System.out.println("Thread 3 is ready.");try {cyclicBarrier.await(); // 等待其他线程到达System.out.println("Thread 3 is executing.");} catch (Exception e) {e.printStackTrace();}}).start();}
}

在这个示例中,CyclicBarrier 通过 await 操作提供了多个线程互相等待,当所有线程都到达屏障后,同时执行后续操作的功能。


最后的话

  • 整理不易,如果对你有用,请给个在看,谢谢~~
  • 如有不正确的地方,请予以指正。【W:编程心声】
  • 如有任何问题,关注公众号编程心声后,留言即可。

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

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

相关文章

探究振弦采集仪在工程监测中的应用

探究振弦采集仪在工程监测中的应用 振弦采集仪是一种专门用于测量结构振动的仪器&#xff0c;在工程监测中有着广泛的应用。它通过采集振动信号&#xff0c;分析结构的振动特性&#xff0c;从而评估结构的安全性能&#xff0c;指导工程设计和施工。本文将从振弦采集仪的基本原…

【日志技术】附Logback入门教程

文章目录 日志概论日志的体系Logback快速入门日志配置文件配置日志级别 日志概论 什么是日志&#xff1f;其实可以通过下面几个问题来了解的。 系统系统能记住某些数据被谁操作&#xff0c;比如被谁删除了&#xff1f;想分析用户浏览系统的具体情况&#xff0c;比如挖掘用户的…

香港麦理浩径一二段两天徒步沙滩露营

文章目录 香港麦理浩径一二段两天徒步沙滩露营 香港麦理浩径一二段两天徒步沙滩露营 凌晨六点起床慢跑7.5公里&#xff0c; 回去洗澡&#xff0c;然后给自己煮了早餐吃完出发时已是早上八点半了。 我在地铁上&#xff0c;中途看了群信息&#xff0c;说要准备港币&#xff0c;…

cache教程 5.分布式节点的通信

0.对原教程的一些见解 其回顾完请求流程就是抽象了两个接口&#xff0c;PeerPicker和PeerGetter。这样操作&#xff0c;读者阅读时可能很难快速明白其含义&#xff0c;不好理解为什么就创建出两个接口&#xff0c;感觉会比较疑惑。原教程的评论中也有讨论这点。 本教程就先不创…

『 Linux 』进程地址空间概念

文章目录 &#x1fad9; 前言&#x1fad9; 进程地址空间是什么&#x1fad9; 写时拷贝&#x1fad9; 可执行程序中的虚拟地址&#x1fad9; 物理地址分布方式 &#x1fad9; 前言 在c/C中存在一种内存的概念; 一般来说一个内存的空间分布包括栈区,堆区,代码段等等; 且内存是…

精通C语言函数,轻松入门!通过实例掌握技巧

一、题目&#xff1a; 1~n的倒数相加&#xff0c;即&#xff1a;1 1/2 1/3 …… 1/n 二、上代码&#xff1a; #include <stdio.h> double fun(int n) // 定义一个函数&#xff0c;参数为n&#xff08;形参&#xff09; { double sum 0; // 初始化…

vue3+vite4中使用svg,使用iconfont-svg图标

记录一下vue3中如何使用svg图标&#xff0c;vue2中大家常用iconfont字体图标&#xff0c;现在vue3大家都又推荐svg的方式使用图表&#xff0c;包括elementplus组件库也变成使用svg方式引用图标。 1、创建svg组件 components/IconSvg.vue <template><svg class"…

代理模式:解析对象间的间接访问与控制

目录 引言 理解代理模式 不同类型的代理模式 代理模式的应用场景 代理模式的优缺点 优点 缺点 实际案例&#xff1a;Java中的代理模式应用 结语 引言 代理模式是软件设计模式中的一种结构型模式&#xff0c;旨在为其他对象提供一种代理以控制对这个对象的访问。它允许你…

改造项目用 开口互感器AKH-0.66/KK-∮24 操作方便,节约时间!

1.产品特点 产品外形美观&#xff0c;安装、接线方便&#xff0c;主要用于电力运维及用电改造项目&#xff0c;一般输出为 AC 5A、 1A 或者毫安等信号&#xff0c;具有体积小、精度高、带载能力强、安装方便等优点&#xff0c;为用户改造项 目节省人力、物力、财力&#xff0c…

php之jwt使用

PHP JWT&#xff08;JSON Web Token&#xff09;是一种用于身份验证和授权的开放标准。JWT是一个包含有关用户或实体身份信息的安全令牌&#xff0c;它由三部分组成&#xff1a;头部&#xff08;Header&#xff09;、载荷&#xff08;Payload&#xff09;和签名&#xff08;Sig…

蓝桥杯周赛 第 1 场 强者挑战赛 6. 小球碰撞【算法赛】(思维题/最长上升子序列LIS)

题目 https://www.lanqiao.cn/problems/9494/learning/?contest_id153 思路来源 Aging代码 题解 二分时间t&#xff0c;第i个小球对应一个起点pi、终点pit*vi的区间&#xff0c;问题转化为&#xff0c; 选最多的区间&#xff0c;使得不存在区间包含&#xff08;即li<l…

Goby 漏洞发布| 亿赛通电子文档安全管理系统 LinkFilterService 接口权限绕过漏洞

漏洞名称&#xff1a;亿赛通电子文档安全管理系统 LinkFilterService 接口权限绕过漏洞 English Name&#xff1a;Esafenet Electronic Document Security Management System LinkFilterService API Permission Bypass Vulnerability CVSS core: 9.3 影响资产数&#xff1a;…