同步容器是通过synchronized来实现同步的,所以性能较差。而且同步容器也并不是绝对线程安全的,在一些特殊情况下也会出现线程不安全的行为。那么有没有更好的方式代替同步容器呢?----> 那就是并发容器,有了并发容器后同步容器的使用也越来越少的,大部分都会优先使用并发容器(J.U.C)。

文章目录

  • 并发容器
  • 并发容器特性
  • CopyOnWriteArrayList实例
  • CopyOnWriteArraySet实例
  • ConcurrentSkipListSet实例
  • ConcurrentHashMap实例
  • ConcurrentSkipListMap实例
  • 本文小结

并发容器

传统容器与并发容器之间的对应关系


并发容器特性

  1. CopyOnWriteArrayList、CopyOnWriteArraySet因为需要copy数组,需要消耗内存,可能引发yonggc或者 fullgc,并且不能做到实时性,适合读多写少的情景
  2. ConcurrentSkipListSet 支持自然排序,并且可以在构造的时候自己定义比较器,可以保证每一次的操作是原子性的,比如add、remove等,但是对于批量操作,如addAll()等并不能保证原子性(需要自己手动做同步操作,如加锁等)
  3. ConcurrentHashMap针对读操作做了大量的优化,这个类具有特别高的并发性,高并发场景下有特别好的表现
  4. ConcurrentSkipListMap与ConcurrentHashMap相比的key是有序的,它支持更高的并发,它的存取时间和线程数是没有关系的,在一定的数据量下,并发的线程越多ConcurrentSkipListMap越能体现出它的优势来

CopyOnWriteArrayList实例

package cn.wideth.util;import java.util.List;
import java.util.concurrent.*;public class MyCopyOnWriteArrayList {//请求总数private static int acquireTotal = 10000;//同时并发执行的线程数目private static int threadTotal = 200;private static List<Integer> list = new CopyOnWriteArrayList<>();public static void main(String[] args) {ExecutorService es = Executors.newCachedThreadPool();final Semaphore semaphore = new Semaphore(threadTotal);final CountDownLatch countDownLatch = new CountDownLatch(acquireTotal);for(int i = 0; i < acquireTotal; i++){final int count = i;es.execute(() -> {try {semaphore.acquire();updateAcquireNumber(count);semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}countDownLatch.countDown();});}try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}es.shutdown();System.out.println("请求总数" + "--> " + list.size());}private static void updateAcquireNumber(int count) {list.add(count);}
}

运行结果


CopyOnWriteArraySet实例

package cn.wideth.util;import java.util.Set;
import java.util.concurrent.*;public class MyCopyOnWriteArraySet {//请求总数private static int acquireTotal = 10000;//同时并发执行的线程数目private static int threadTotal = 200;private static Set<Integer> set = new CopyOnWriteArraySet<>();public static void main(String[] args) {ExecutorService es = Executors.newCachedThreadPool();final Semaphore semaphore = new Semaphore(threadTotal);final CountDownLatch countDownLatch = new CountDownLatch(acquireTotal);for(int i = 0; i < acquireTotal; i++){final int count = i;es.execute(() -> {try {semaphore.acquire();updateAcquireNumber(count);semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}countDownLatch.countDown();});}try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}es.shutdown();System.out.println("请求总数" + "--> " + set.size());}private static void updateAcquireNumber(int count) {set.add(count);}
}

运行结果


ConcurrentSkipListSet实例

package cn.wideth.util;import java.util.Set;
import java.util.concurrent.*;public class MyConcurrentSkipListSet {//请求总数private static int acquireTotal = 10000;//同时并发执行的线程数目private static int threadTotal = 200;private static Set<Integer> set = new ConcurrentSkipListSet<>();public static void main(String[] args) {ExecutorService es = Executors.newCachedThreadPool();final Semaphore semaphore = new Semaphore(threadTotal);final CountDownLatch countDownLatch = new CountDownLatch(acquireTotal);for(int i = 0; i < acquireTotal; i++){final int count = i;es.execute(() -> {try {semaphore.acquire();updateAcquireNumber(count);semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}countDownLatch.countDown();});}try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}es.shutdown();System.out.println("请求总数" + "--> " + set.size());}private static void updateAcquireNumber(int count) {set.add(count);}
}

运行结果


ConcurrentHashMap实例

package cn.wideth.util;import java.util.Map;
import java.util.concurrent.*;public class MyConcurrentHashMap {//请求总数private static int acquireTotal = 10000;//同时并发执行的线程数目private static int threadTotal = 200;private static Map<Integer,Integer> map = new ConcurrentHashMap<>();public static void main(String[] args) {ExecutorService es = Executors.newCachedThreadPool();final Semaphore semaphore = new Semaphore(threadTotal);final CountDownLatch countDownLatch = new CountDownLatch(acquireTotal);for(int i = 0; i < acquireTotal; i++){final int count = i;es.execute(() -> {try {semaphore.acquire();updateAcquireNumber(count);semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}countDownLatch.countDown();});}try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}es.shutdown();System.out.println("请求总数" + "--> " + map.size());}private static void updateAcquireNumber(int count) {map.put(count,count);}
}

运行结果


ConcurrentSkipListMap实例

package cn.wideth.util;import java.util.Map;
import java.util.concurrent.*;public class MyConcurrentSkipListMap {//请求总数private static int acquireTotal = 10000;//同时并发执行的线程数目private static int threadTotal = 200;private static Map<Integer,Integer> map = new ConcurrentSkipListMap<>();public static void main(String[] args) {ExecutorService es = Executors.newCachedThreadPool();final Semaphore semaphore = new Semaphore(threadTotal);final CountDownLatch countDownLatch = new CountDownLatch(acquireTotal);for(int i = 0; i < acquireTotal; i++){final int count = i;es.execute(() -> {try {semaphore.acquire();updateAcquireNumber(count);semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}countDownLatch.countDown();});}try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}es.shutdown();System.out.println("请求总数" + "--> " + map.size());}private static void updateAcquireNumber(int count) {map.put(count,count);}
}

运行结果


本文小结

本文给出了juc中几种常见的集合类的代码实现,具体的API请看对应的文档。

并发容器(J.U.C)中的集合类相关推荐

  1. 并发容器(J.U.C)中的队列类

    JUC包下的容器类分为两部分,一部分是并发集合类,一部分是并发队列类,其中并发集合类可以解决我们集合使用过程中的多线程并发问题,而并发队列类则主要被当做阻塞队列使用,是线程池中的关键参数之一. 文章目 ...

  2. 并发容器J.U.C -- AQS组件(一)

    AQS简介 AQS全名:AbstractQueuedSynchronizer,是并发容器J.U.C(java.lang.concurrent)下locks包内的一个类.它实现了一个FIFO的队列.底层 ...

  3. java高并发(十二)并发容器J.U.C

    并发容器是JDK提供的一个包名:java.util.concurrent ArrayList -> CopyOnWriteArrayList CopyOnWriteArrayList是线程安全的 ...

  4. Java并发容器J.U.C

    J.U.C是java.util.concurrent的简写,里面提供了很多线程安全的集合. CopyOnWriteArrayList介绍 CopyOnWriteArrayList相比于ArrayLis ...

  5. java高并发(十三)并发容器J.U.C--AQS

    AbstractQueueSynchronizer (AQS) J.U.C 大大提高了java并发的性能,而AQS则是J.U.C的核心. AQS底层使用双向列表(队列的一种实现). 使用Node实现F ...

  6. 并发编程-14线程安全策略之并发容器(J.U.C)中的集合类

    文章目录 J.U.C总览 脑图 概述 并发容器特性 示例 ArrayList对应的线程安全的并发容器类CopyOnWriteArrayList (线程安全) HashSet对应的线程安全的并发容器类C ...

  7. Java并发(9)- 从同步容器到并发容器

    引言 容器是Java基础类库中使用频率最高的一部分,Java集合包中提供了大量的容器类来帮组我们简化开发,我前面的文章中对Java集合包中的关键容器进行过一个系列的分析,但这些集合类都是非线程安全的, ...

  8. 高并发编程_高并发编程系列:7大并发容器详解(附面试题和企业编程指南)...

    不知道从什么时候起,在Java编程中,经常听到Java集合类,同步容器.并发容器,高并发编程成为当下程序员需要去了解掌握的技术之一,那么他们有哪些具体分类,以及各自之间的区别和优劣呢? 只有把这些梳理 ...

  9. 死磕Java并发:J.U.C之阻塞队列:ArrayBlockingQueue

    作者:chenssy 来源:Java技术驿站 ArrayBlockingQueue,一个由数组实现的有界阻塞队列.该队列采用FIFO的原则对元素进行排序添加的. ArrayBlockingQueue为 ...

最新文章

  1. wpf richtextbox 存储到数据库并显示
  2. VS2010 ASP.NET MVC4 安装失败问题
  3. 阿里云发布ECS磁盘加密,一键加密,业务0改动
  4. 【STM32】FreeRTOS 中断配置和临界段
  5. Boostrap的按钮下拉菜单
  6. Android 退出应用程序
  7. 【转】汇总:LDA理论、变形、优化、应用、工具库
  8. Spring-SpringMVC父子容器
  9. srtvlet filter
  10. Android 架构艺术之MVP
  11. PreScan传感器(零)——通用配置
  12. 期刊论文格式模板 电子版_期刊论文发表流程是怎样的呢?
  13. 社区团购猛地火了,有没有美团、拼多多这样的命?
  14. 联想笔记本e43l_联想昭阳e43l
  15. 苹果4s怎么越狱_iPhone 12系列细节曝光:苹果调整屏幕尺寸
  16. POI导出word单元格合并
  17. php 502 bad gateway 解决方法
  18. 1445. 苹果和桔子
  19. Redis基本类型-结合Set
  20. AI失业,出路何在?

热门文章

  1. struct 和enum的用法
  2. 并发 - 生产者消费者的问题
  3. 支付宝当前最新版集成2.1.2版本
  4. Struts2的struts.xml的配置细节
  5. XP远程桌面连接2008提示:远程计算机需要网络级别身份验证,而您的计算机不支持该验证...
  6. 如何在eclipse中使用XYLayout布局?在此介绍如何把XYLayout导入到eclipse .
  7. 用户、组织结构、功能菜单、权限分配设计
  8. 探寻完美 之 JavaScript继承
  9. 使用NBAR更有效的识别与封堵网络应用
  10. win10安装python