java并发容器(Map、List、BlockingQueue)

LinkedBlockingQueue 链式阻塞队列的使用方法和原理 相关性文章: 了解BlockingQueue 大体框架和实现思路 并发相关文章: ReentrantLock源码 解析AQS锁加锁释放锁的实现机制 CAS算法详解 ABA问题以及解决办法 目录 概览 使用方法 源码解析 说明 队列容器 结构图 next三种情况 入队操作 出队操作 关键成员变量 初始化 put方法 put方法几个关注点 总体分析 count属性并发问题 唤醒消费者 take方法 总结 概览 1. 基于链表的可选有界阻塞队列。根据F.. 阅读详情

早期同步容器问题

Java库本身就有多种线程安全的容器和同步工具,其中同步容器包括两部分:一个是Vector和Hashtable。另外还有JDK1.2中加入的同步包装类,这些类都是由Collections.synchronizedXXX工厂方法。同步容器都是线程安全的,但是对于复合操作,还有些缺点:

① 迭代:在查觉到容器在迭代开始以后被修改,会抛出一个未检查异常ConcurrentModificationException,为了避免这个异常,需要在迭代期间,持有一个容器锁。但是锁的缺点也很明显,就是对性能的影响。

② 隐藏迭代器:StringBuilder的toString方法会通过迭代容器中的每个元素,另外容器的hashCode和equals方法也会间接地调用迭代。类似地,contailAll、removeAll、retainAll方法,以及容器作为参数的构造函数,都会对容器进行迭代。

③ 缺少即加入等一些复合操作

public static Object getLast(Vector list) {         int lastIndex = list.size() - 1;         return list.get(lastIndex);}public static void deleteLast(Vector list) {         int lastIndex = list.size() - 1;         list.remove(lastIndex);}

getLast和deleteLast都是复合操作,由先前对原子性的分析可以判断,这依然存在线程安全问题,有可能会抛出ArrayIndexOutOfBoundsException的异常,错误产生的逻辑如下所示:

 

解决办法就是通过对这些复合操作加锁

1 并发容器类

正是由于同步容器类有以上问题,导致这些类成了鸡肋,于是Java 5推出了并发容器类,Map对应的有ConcurrentHashMap,List对应的有CopyOnWriteArrayList。与同步容器类相比,它有以下特性:

1.1 ConcurrentHashMap

· 更加细化的锁机制。同步容器直接把容器对象做为锁,这样就把所有操作串行化,其实这是没必要的,过于悲观,而并发容器采用更细粒度的锁机制,名叫分离锁,保证一些不会发生并发问题的操作进行并行执行

· 附加了一些原子性的复合操作。比如putIfAbsent方法

· 迭代器的弱一致性,而非“及时失败”。它在迭代过程中不再抛出Concurrentmodificationexception异常,而是弱一致性。

· 在并发高的情况下,有可能size和isEmpty方法不准确,但真正在并发环境下这些方法也没什么作用。

· 另外,它还有一些附加的原子操作,缺少即加入、相等便移除、相等便替换。

putIfAbsent(K key, V value),缺少即加入(如果该键已经存在,则不加入)           如果指定键已经不再与某个值相关联,则将它与给定值关联。

类似于下面的操作

If(!map.containsKey(key)){    return map.put(key,value);}else{    return map.get(key);}

remove(Object key, Object value),相等便移除           只有目前将键的条目映射到给定值时,才移除该键的条目。

类似于下面的:

if(map.containsKey(key) && map.get(key).equals(value)){    Map.remove();    return true;}else{    return false;}

replace(K key, V value)

replace(K key, V oldValue, V newValue),相等便替换。           只有目前将键的条目映射到某一值时,才替换该键的条目。

上面提到的三个,都是原子的。在一些缓存应用中可以考虑代替HashMap/Hashtable。

1.2 CopyOnWriteArrayList和CopyOnWriteArraySet

· CopyOnWriteArrayList采用写入时复制的方式避开并发问题。这其实是通过冗余和不可变性来解决并发问题,在性能上会有比较大的代价,但如果写入的操作远远小于迭代和读操作,那么性能就差别不大了。

应用它们的场合通常在数组相对较小,并且遍历操作的数量大大超过可变操作的数量时,这种场合应用它们非常好。它们所有可变的操作都是先取得后台数组的副本,对副本进行更改,然后替换副本,这样可以保证永远不会抛出ConcurrentModificationException移除。

2 队列

Java中的队列接口就是Queue,它有会抛出异常的add、remove方法,在队尾插入元素以及对头移除元素,还有不会抛出异常的,对应的offer、poll方法。

2.1 LinkedList

List实现了deque接口以及List接口,可以将它看做是这两种的任何一种。

Queue queue=new LinkedList();queue.offer("testone");queue.offer("testtwo");queue.offer("testthree");queue.offer("testfour");System.out.println(queue.poll());

2.2 PriorityQueue

一个基于优先级堆(简单的使用链表的话,可能插入的效率会比较低O(N))的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。优先级队列不允许使用 null 元素。依靠自然顺序的优先级队列还不允许插入不可比较的对象。

queue=new PriorityQueue();queue.offer("testone");queue.offer("testtwo");queue.offer("testthree");queue.offer("testfour");System.out.println(queue.poll());

2.3 ConcurrentLinkedQueue

基于链节点的,线程安全的队列。并发访问不需要同步。在队列的尾部添加元素,并在头部删除他们。所以只要不需要知道队列的大小,并发队列就是比较好的选择。

3 阻塞队列

3.1 生产者和消费者模式

生产者和消费者模式,生产者不需要知道消费者的身份或者数量,甚至根本没有消费者,他们只负责把数据放入队列。类似地,消费者也不需要知道生产者是谁,以及是谁给他们安排的工作。

而Java知道大家清楚这个模式的并发复杂性,于是乎提供了阻塞队列(BlockingQueue)来满足这个模式的需求。阻塞队列说起来很简单,就是当队满的时候写线程会等待,直到队列不满的时候;当队空的时候读线程会等待,直到队不空的时候。实现这种模式的方法很多,其区别也就在于谁的消耗更低和等待的策略更优。以LinkedBlockingQueue的具体实现为例,它的put源码如下:

public void put(E e) throws InterruptedException {        if (e == null) throw new NullPointerException();        int c = -1;        final ReentrantLock putLock = this.putLock;        final AtomicInteger count = this.count;        putLock.lockInterruptibly();        try {                        try {                while (count.get() == capacity)                    notFull.await();            } catch (InterruptedException ie) {                notFull.signal(); // propagate to a non-interrupted thread                throw ie;            }            insert(e);            c = count.getAndIncrement();            if (c + 1 < capacity)                notFull.signal();        } finally {            putLock.unlock();        }        if (c == 0)            signalNotEmpty();}

撇开其锁的具体实现,其流程就是我们在操作系统课上学习到的标准生产者模式,看来那些枯燥的理论还是有用武之地的。其中,最核心的还是Java的锁实现,有兴趣可以再进一步深究一下。

阻塞队列Blocking queue,提供了可阻塞的put和take方法,他们与可定时的offer和poll方法是等价。Put方法简化了处理,如果是有界队列,那么当队列满的时候,生成者就会阻塞,从而改消费者更多的追赶速度。

3.2 ArrayBlockingQueue和LinkedBlockingQueue

FIFO的队列,与LinkedList(由链节点支持,无界)和ArrayList(由数组支持,有界)相似(Linked有更好的插入和移除性能,Array有更好的查找性能,考虑到阻塞队列的特性,移除头部,加入尾部,两个都区别不大),但是却拥有比同步List更好的并发性能。

另外,LinkedList永远不会等待,因为他是无界的。

BlockingQueue<String> queue=new ArrayBlockingQueue<String>(5); Producer p=new Producer(queue);Consumer c1=new Consumer(queue);Consumer c2=new Consumer(queue); new Thread(p).start();new Thread(c1).start();new Thread(c2).start(); /** * 生产者 * @author Administrator * */class Producer implements Runnable {   private final BlockingQueue queue;   Producer(BlockingQueue q) { queue = q; }      public void run() {     try {          for(int i=0;i<100;i++){              queue.put(produce());          }           } catch (InterruptedException ex) {}   }      String produce() {       String temp=""+(char)('A'+(int)(Math.random()*26));       System.out.println("produce"+temp);       return temp;   } } /** * 消费者 * @author Administrator * */class Consumer implements Runnable {   private final BlockingQueue queue;   Consumer(BlockingQueue q) { queue = q; }   public void run() {     try {      for(int i=0;i<100;i++){          consume(queue.take());      }     } catch (InterruptedException ex) {}   }   void consume(Object x) {       System.out.println("cousume"+x.toString());   } } 输出:produceKcousumeKproduceVcousumeVproduceQcousumeQproduceIproduceDproduceIproduceGproduceAproduceEcousumeD

3.3 PriorityBlockingQueue

一个按优先级堆支持的无界优先级队列,如果不希望按照FIFO的顺序进行处理,它非常有用。它可以比较元素本身的自然顺序,也可以使用一个Comparator排序。

3.4 DelayQueue

一个优先级堆支持的,基于时间的调度队列。加入到队列中的元素必须实现新的Delayed接口(只有一个方法,Long getDelay(java.util.concurrent.TimeUnit unit)),添加可以理立即返回,但是在延迟时间过去之前,不能从队列中取出元素,如果多个元素的延迟时间已到,那么最早失效链接/失效时间最长的元素将第一个取出。

static class NanoDelay implements Delayed{long tigger;      NanoDelay(long i){    tigger=System.nanoTime()+i;} public boolean equals(Object other){    return ((NanoDelay)other).tigger==tigger;} /** * 返回此对象相关的剩余延迟时间,零或负值指示延迟时间已经用尽 */public long getDelay(TimeUnit unit) {    long n=tigger-System.nanoTime();    return unit.convert(n, TimeUnit.NANOSECONDS);} public long getTriggerTime(){    return tigger;} /** * 相互比较,看谁的实效时间最长,谁先出去 */public int compareTo(Delayed o) {    long i=tigger;    long j=((NanoDelay)o).tigger;    if(i<j){        return -1;    }    if(i>j)        return 1;    return 0;} } public static void main(String[] args) throws InterruptedException{    Random random=new Random();    DelayQueue<NanoDelay> queue=new DelayQueue<NanoDelay>();    for(int i=0;i<5;i++){        queue.add(new NanoDelay(random.nextInt(1000)));    }    long last=0;    for(int i=0;i<5;i++){        NanoDelay delay=(NanoDelay)(queue.take());        long tt=delay.getTriggerTime();        System.out.println("Trigger time:"+tt);                 if(i!=0){            System.out.println("Data: "+(tt-last));        }        last=tt;    } }

3.5 SynchronousQueue

不是一个真正的队列,因为它不会为队列元素维护任何存储空间,不过它维护一个排队的线程清单,这些线程等待把元素加入(enqueue)队列或者移出(dequeue)队列。也就是说,它非常直接的移交工作,减少了生产者和消费者之间移动数据的延迟时间,另外,也可以更快的知道反馈信息,当移交被接受时,它就知道消费者已经得到了任务。

因为SynChronousQueue没有存储的能力,所以除非另一个线程已经做好准备,否则put和take会一直阻止。它只有在消费者比较充足的时候比较合适。

4 双端队列(Deque)

JAVA6中新增了两个容器Deque和BlockingDeque,他们分别扩展了Queue和BlockingQueue。Deque它是一个双端队列,允许高效的在头和尾分别进行插入和删除,它的实现分别是ArrayDeque和LinkedBlockingQueue。

双端队列使得他们能够工作在一种称为“窃取工作”的模式上面。

5 最佳实践

1..同步的(synchronized)+HashMap,如果不存在,则计算,然后加入,该方法需要同步。

HashMap cache=new HashMap();public synchronized V compute(A arg){    V result=cace.get(arg);    if(result==null){        result=c.compute(arg);        cache.put(result);    }    return result;}

2.用ConcurrentHashMap代替HashMap+同步.,这样的在get和set的时候也基本能保证原子性。但是会带来重复计算的问题.

Map<A,V> cache=new ConcurrentHashMap<A,V>();public  V compute(A arg){    V result=cace.get(arg);    if(result==null){        result=c.compute(arg);        cache.put(result);    }    return result;}

3.采用FutureTask代替直接存储值,这样可以在一开始创建的时候就将Task加入

Map<A,FutureTask<V>> cache=new ConcurrentHashMap<A,FutureTask<V>>();public  V compute(A arg){    FutureTask <T> f=cace.get(arg);    //检查再运行的缺陷    if(f==null){        Callable<V> evel=new Callable(){            Public V call() throws ..{                return c.compute(arg);            }        };        FutureTask <T> ft=new FutureTask<T>(evel);        f=ft;        cache.put(arg,ft;        ft.run();    }    Try{        //阻塞,直到完成        return f.get();    }cach(){    }}

4.上面还有检查再运行的缺陷,在高并发的情况下啊,双方都没发现FutureTask,并且都放入Map(后一个被前一个替代),都开始了计算。

这里的解决方案在于,当他们都要放入Map的时候,如果可以有原子方法,那么已经有了以后,后一个FutureTask就加入,并且启动。

public  V compute(A arg){    FutureTask <T> f=cace.get(arg);    //检查再运行的缺陷    if(f==null){        Callable<V> evel=new Callable(){            Public V call() throws ..{                return c.compute(arg);            }        };        FutureTask <T> ft=new FutureTask<T>(evel);        f=cache.putIfAbsent(args,ft); //如果已经存在,返回存在的值,否则返回null        if(f==null){f=ft;ft.run();} //以前不存在,说明应该开始这个计算        else{ft=null;} //取消该计算    }    Try{        //阻塞,直到完成        return f.get();    }cach(){    }}

5.上面的程序上来看已经完美了,不过可能带来缓存污染的可能性。如果一个计算被取消或者失败,那么这个键以后的值永远都是失败了;一种解决方案是,发现取消或者失败的task,就移除它,如果有Exception,也移除。

6.另外,如果考虑缓存过期的问题,可以为每个结果关联一个过期时间,并周期性的扫描,清除过期的缓存。(过期时间可以用Delayed接口实现,参考DelayQueue,给他一个大于当前时间XXX的时间,,并且不断减去当前时间,直到返回负数,说明延迟时间已到了。)

无人机三维路径规划:深度强化学习与A*混合算法详解 路径规划是无人机自主飞行的核心技术,在复杂三维环境中需要兼顾避障安全与到达效率。传统A*搜索算法依赖栅格离散化,面对连续空间时节点爆炸且缺乏动态适应能力;而深度强化学习虽能学习连续动作策略,但单一策略难以保证任意随机地图下的绝对安全。近端策略优化(PPO)作为稳定的连续控制算法,通过演员-评论家结构和高斯动作分布输出三维方向与步长,配合距离差分奖励函数引导智能体逐步逼近目标。与此同时,三维A*搜索作为兜底机制,在强化学习路线失败时提供可验证的安全路径,并由统一评价器综合路径长度、转向代价与障碍距离选优。这种 阅读详情

相关推荐

学习海康VisionMaster之圆查找

(1):ROI选中位置修正,并且修正信息需要选择刚刚创建的位置修正组件输出信息,这里的话后续的检测窗口一般都需要做这一步,因为大部分的应用场景都是需要用到实时跟踪的。圆查找模块是用于查找指定区域的圆,并且会输出该圆的相关参数信息,比如圆中心点,圆半径,圆是否存在等信息。7):剔除点数:和高级参数里面的剔除距离搭配使用的,就是过滤较远的边缘点,让拟合圆心出来的轮廓更加接近。中的圆查找,相当于就是拟合圆心,这个在视觉软件中的应用也是非常广泛的,通常用于定位,测量项目。

yuhouxiyang的专栏 2100

java 数据结构大全(Map、List、Set、BlockingQueue、BlockingDueue)

1、集合框架 下面这个图基本包括了java中核心的集合结构,个人觉得还可以。 1.1、Iterable 接口 这个接口是集合系列的根接口,都要实现它,因为 Iterable 接口里面有个iterator()方法,用于遍历集合里的每一个元素,所以记着:凡是集合类,都可以通过iterator来遍历。 1.2、 Collection接口 public interface Collection<E> extends Iterable<E> { // 返回集合的元素个数

dgh112233的博客 665

基于Hadoop生态的大数据异常检测平台搭建

批处理:用Spark MLlib的LOF(局部异常因子,适合高密度数据)、(单类支持向量机,适合高维数据);流处理:用Flink ML的(实时聚类,检测离群点)、ADWIN(自适应滑动窗口,处理概念漂移)。数据层:用Flume/Kafka采集数据,HDFS存储,Hive管理元数据;计算层:用Spark处理离线批数据,Flink处理实时流数据;算法层:用孤立森林(批)、3σ原则(流)检测异常;可视化层:用Grafana做仪表盘,Prometheus+Alertmanager报警。这个平台能处理。

软件工程实践的博客 933

Java之Queue与Map集合

一、Queue 1.特点: 和数据结构中的队列类似,只允许在队头删除元素,队尾插入元素。队列中允许有重复的元素。 2.Queue中的方法 2.1 插入元素 boolean add(E element) boolean offer(E element) 说明:二者都是向队列中添加元素,如果成功,返回true。区别在于当队列已满时,add()抛出IllegalStateExcepti...

smell201611010513的博客 1544

Nvidia Isaac Sim图形界面 入门教程 2024(3)

在使用Isaac Sim时,最先接触到的应该是它的图形界面,此处将简单介绍图形界面中常用的一些组件:Isaac Sim的界面的常用内容可以分为几个板块。

m0_56661101的博客 4546

Nacos启动报错No DataSource set?5分钟搞定standalone模式配置

本文针对Nacos启动时常见的“No DataSource set”报错,深入解析了其根源在于默认集群模式与外部数据库依赖。提供了两种快速解决方案:通过命令行参数“-m standalone”启动,或直接修改启动脚本配置文件,从而在5分钟内以单机模式成功启动Nacos,无需配置MySQL数据库。

weixin_29234509的博客 464

List、Map并发解决方法

List、Map并发解决方法1、出现现象2、解决办法3、Map 1、出现现象 当我们用多个线程对ArrayList进行添加操作的时候,会出现异常信息 ConcurrentModificationException 下面放上代码 public class ListTest { public static void main(String[] args) { //ArrayList 不安全的 synchronized List<Object> list =

qq_44392492的博客 487

Flutter项目在M1/M2 Mac上跑iOS模拟器报错?手把手教你搞定‘arm64架构不兼容’问题

本文详细解析了Flutter项目在M1/M2 Mac上运行iOS模拟器时遇到的‘arm64架构不兼容’问题,提供了多种解决方案,包括排除模拟器的arm64架构、强制使用x86_64架构以及修改插件Podspec文件。帮助开发者快速解决架构兼容性问题,提升开发效率。

weixin_33713707的博客 335

java并发容器(Map、List、BlockingQueue)详解

Java库本身就有多种线程安全的容器和同步工具,其中同步容器包括两部分:一个是Vector和Hashtable。另外还有JDK1.2中加入的同步包装类,这些类都是由Collections.synchronizedXXX工厂方法。同步容器都是线程安全的,但是对于复合操作,缺有些缺点: ① 迭代:在查觉到容器在迭代开始以后被修改,会抛出一个未检查异常ConcurrentModificationExc

li295214001的专栏 5238

保姆级教程:如何将仅限客户端使用的免费大模型(Gemini、Antigravity、Qwen Code、Kiro 等)转为任何应用可调用的 OpenAI 兼容标准接口

大模型 API 费用太贵?💸 这篇文章分享一个薅羊毛神器,能把 Gemini、Qwen Code、Kiro 等客户端专属的免费大模型转换成标准 OpenAI 兼容接口 🔌。支持多协议互转、账户池管理、Web 管理界面,Docker 一键部署,零成本调用 Claude Opus 4.5、Gemini 3 Pro 等高级模型 ✅

XiaoqiangClub的博客 1033

Proxmox(pve)集群(4)存储(1)配置分布式存储ceph

它使用一种称为CRUSH(Controlled Replication Under Scalable Hashing)算法的数据分布算法来将数据均匀地分布在多个存储节点上,并确保数据的冗余和容错。它负责管理数据的分布、冗余和自动修复。PVE支持本地存储、LVM、NFS、iSCSI、CephFS、RBD、ZFS等存储方式,我这里使用两种存储方式,一种是通过ceph实现分布式存储,一种是通过truenas实现集中式存储。自我管理和自动恢复:Ceph具有自我管理的特性,可以动态地调整和优化存储集群的配置。

Monster✺◟(∗❛ัᴗ❛ั∗)◞✺的博客 2623

java并发容器(Map、List、BlockingQueue)具体解释

Java库本身就有多种线程安全的容器和同步工具,当中同步容器包含两部分:一个是Vector和Hashtable。另外还有JDK1.2中增加的同步包装类。这些类都是由Collections.synchronizedXXX工厂方法。同步容器都是线程安全的,可是对于复合操作。缺有些缺点: ① 迭代:在查觉到容器在迭代開始以后被改动,会抛出一个未检查异常ConcurrentModificatio...

weixin_34234823的博客 328

19、英国模式:银行体系的演变与现代金融架构

本文深入探讨了英国银行体系从专业化向全能银行的演变过程,分析了自律监管模式的优劣,并解析了围栏制度对金融稳定的影响。同时,文章还介绍了信用合作社、建筑协会和投资银行的角色与转型,全面展示了英国金融体系的多样性与复杂性,以及其在全球金融市场中的重要作用。

embedding5hiker的博客 104

Java工具并发容器

JDK 1.7 中, ConcurrentHashMap 类中包含静态内部类 Segment,继承于 ReentrantLock 类用来充当锁的角色,每个 Segment 对象守护若干个保存键值对的链表,共同构成 ConcurrentHashMap 实例中的数组。【阻塞队列】被广泛使用在“生产者-消费者”问题中,其原因是 BlockingQueue 提供了可阻塞的插入和移除的方法。Java 提供的基础容器都是线程不安全的,如果并发条件下多个线程同时对一个容器中的数据进行操作,可能会导致各种意想不到的错误。

2401_84881237的博客 1233

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

并发容器.

JDK 1.7 中, ConcurrentHashMap 类中包含静态内部类 Segment,继承于 ReentrantLock 类用来充当锁的角色,每个 Segment 对象守护若干个保存键值对的链表,共同构成 ConcurrentHashMap 实例中的数组。【阻塞队列】被广泛使用在“生产者-消费者”问题中,其原因是 BlockingQueue 提供了可阻塞的插入和移除的方法。Java 提供的基础容器都是线程不安全的,如果并发条件下多个线程同时对一个容器中的数据进行操作,可能会导致各种意想不到的错误。

2401_84881237的博客 440

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

知识链-Java多线程并发

Java多线程并发java并发容器(Map、List、BlockingQueue)

秀才的专栏 2849

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java容器有哪些?哪些是同步容器,哪些是并发容器?

容器:用于保存对象并提供完善的方法来保存对象的类; 主要的容器: List ArrayList LinkedList Vector Stack Set SortedSet HashSet TreeSet Queue Map HashMap TreeMap Hashtable SortedMap Collection 常见同步容器: SynchronizedCollec...

qq_40462579的博客 922

java并发容器

java并发容器(Map、List、BlockingQueue) (2011-03-08 17:45:35)转载▼标签: java并发容器maplistblockingqueue杂谈 分类: 架构与开发 Java库本身就有多种线程安全的容器和同步工具,其中同步容器包括两部分:一个是Vector和Hashtable。另外还有JDK1.2中加入的同步包装类,这些类都是由Collections...

foxox 82

java线程深度解析(七)——并发数据结构

http://blog.youkuaiyun.com/Daybreak1209/article/details/51415995 一、并发List 1、Vector 在java核心数据结构(一)——List类族一文中已经提到List类簇中ArrayList和Vector的主要区别就是Vector的大部分实现都支持线程安全,代码也展示了一部分。另外如果使用到ArrayList有

火侬智能科技 1059

多线程(4)-相关容器

1. 容器的实现 物理结构上,就是 数组+链表 利用数组+链表可以实现各种各样的容器 2. 容器的分类 容器分两大类,Collection和 Map,Collection有分为 List Set Queue 3. 容器的演变 3.1 Map Hashtable-----> HashMap-----> synchronizedHashMap----->ConcurrentHashMap(写入效率慢,读快) Hashtable 实现Map接口,是线程安全的,Hashtable 的方法都是s

水月青花 220

JAVA 中的集合

1.Java中有哪些容器? Java中的集合主要有两个接口,Map 和 Collection。 Collection接口的子接口有List, Set, Queue。 常见的实现类: List: LinkedList, ArrayList Set:HashSet, TreeSet(继承于SortedSet接口) Queue: ArrayDeque(继承于Deque) Map: HashMap, HashTable, TreeMap(根据键的大小排序), LinkedHashMap(根据插入顺序排

weixin_45502048的博客 1693
上一篇: ActiveMQ的集群与高可用
下一篇: Java集合容器总结
架构师的清醒
博客等级 码龄14年 291粉丝 397原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值