并发集合框架
同步框架(sysnchronized collections)和并发框架(concurrent collections)的区别。
java5在同步的集合框架方面做了一些改进,提供了几个并发集合类。同步集合类通过序列化对集合状态的访问来保证线程安全。这种方法的代价就是降低并发性;当多个线程竞争这个集合的锁的时候,吞吐量自然降低了。
而并发集合类就是专门被设计出来实现多线程并发访问的。JAVA5增加了ConcurrentHashMap,用来替代基于hash的MAP实现,而CopyOnWriteArrayList是用来替换同步的List的--当遍历是一种常用操作的时候。新的ConcurrentMap接口添加了对一些常用的组合操作的支持,比如put-if-absent,replace,conditional remove。
使用并发集合替换同步集合,会大幅提高应用的伸缩性,而风险却很低。
JAVA5还新添加了两个新的集合类型,Queue和BlockingQueue.Queue呢,是在里面元素等待处理的过程中,将元素的集合进行加锁。该接口默认提供了几个实现,包括ConcurrentLinkedQueue,一个传统的FIFO队列;PriorityQueue,一个按优先级排序的队列。队列的操作是非阻塞的;如果一个队列是空的,那么获取操作将返回null。你可以将队列的行为当作List来看。实际上,LinkedList也实现了Queue接口,队列类不能进行随机的访问,但是却能有效的增加并发访问量。
BlockingQueue扩展了Queue,添加了阻塞的插入和获取操作。如果队列是空的,那么获取操作将阻塞,直到有一个元素存在为止;同时如果一个队列是null,那么一个插入操作将被阻塞直到有空间为止。阻塞操作在生产者-消费者这种设计中非常的有用,以后进行详述。
JAVA6添加了ConcurrentSkipListMap和ConcurrentSkipListSet两个类,用作同步的SortedMap或者SortedSet的替代品。
ConcurrentHashMap
同步的集合类会在集合的每个操作执行期间持有一个锁。而有些操作,比如HashMap.get或者List.contains,可能比他表面看起来调用更多的操作,比如在遍历一个hash bucket或者List,去查找某个对象的时候,就必须调用他们各自的equals方法(而这些方法本身可能还需要调用别的操作)。在一个基于hash的集合中,如果hashCode没有很好的获得,那么元素的分布将会遇到很多冲突;在最坏的情况下,一个很烂的hash算法可能导致一个hash table变成一个linked list。遍历一个很长的list并在他们上调用equals方法,这需要消耗很长时间,而在这段时间中,其他线程将不能访问该集合。
ConcurrentHashMap 和HashMap是类似的,是基于hash的,但是他使用了一个完全不同的加锁策略,从而提供了更好的并发性和伸缩性。这种加锁策略不是对每个方法进行加锁,限制任意时刻只能单线程访问,他使用了更细粒度的加锁方法,叫做lock striping(姑且叫做锁分离吧),允许更大自由度的访问。任何的读取线程都可以并发访问的map,而且,读取线程和写入线程可并发的访问map,但是只有有限数量的写线程允许并发修改。这么作的结果就是在并发访问下具有更高的吞吐量,而比单线程访问几乎没有性能损失。
ConcurrentHashMap以及其他并发集合,比同步的集合做了些改进,迭代器不再抛出ConcurrentModificationException异常,因此也不再需要在迭代过程中将集合加锁了。ConcurrentHashMap返回的是不稳定的迭代器而不是一个快速失败。一个不稳定的迭代器允许并发修改,并且在迭代过程中,有可能会体现出其他线程的修改(可能但不保证)。
与这些改进一起的,还有一些妥协和折衷。一些对整个Map进行的操作,比如size和isEmpty方法,削弱了对并发集合的反应。由于size()的结果在他被计算出来之后会过期,所以仅仅是个估计值,所以size返回的值是个近似值,而不是精确值。第一次看到这些,可能会比较迷惑,而在真实世界中,像size()和isEmpty()这些方法在并发环境中作用被大大削弱。
有些特性是同步的集合拥有,而并发集合没有的,如对整个map的加锁,保持排他的访问。对于Hashtable和synchronizedMap来说,需要一个map锁,来保证其他线程不能同时访问改对象。这些特性在有些情况下可能是必要的,比如:原子的添加好几个mapping,或者遍历map多次,抑或着需要查看到相同的元素并保持相同的状态。总得来说,这算是比较合理的权衡和妥协:毕竟并发集合本应该就是能被并发的修改。
比起Hashtable和synchronizedMap来说,他的优点很多而缺点很少,所以用来作为Map的实现的替代,在大部分情况下会得到更好的可伸缩性,只有当你的应用需要锁定整个map的时候,ConcurrentHashMap才不适用。
其他原子map操作
由于ConcurrentHashMap不能被锁住,并保持排他的访问,所以,我们不能使用客户端锁来创建一个原子操作,比如put-if-absent。所以ConcurrentHashMap接口定义了put-if-absent,remove-if-equal,replace-if-equal等原子操作,如果你发现自己给已存在的同步集合添加了这些实现,那么似乎就意味着你可能需要用ConcurrentMap来替换你的类。
CopyOnWriteArrayList
CopyOnWriteArrayList是并发集合提供的用以替代同步的List的实现类,在绝大部分情况下,由于他不需要在整个迭代过程中加锁,所以可以提供更好的并发性能。
为什么会有这种copy-on-write的集合出现呢,大家貌似还应该记得,不可变对象如果被正确的发布出来,那么他是不需要任何的锁来控制访问的,所以copy-on-write就是从这里获得的灵感,这种集合当有任何修改时,就会创建并重新发布出一个新的集合。对于这种集合来说他不会抛出ConcurrentModificationException异常,返回的元素是当迭代器创建的时候持有的元素,而没有后续的更改。很显然的是,每次更改都会创建一个新的集合出来,这是有开销的,特别是当集合很大的时候,所以这种集合的适用场合应该是读取比较频繁,而修改操作较少的场合。
分享到:
相关推荐
这本"Java并发编程学习笔记"可能是作者在深入研究Java并发特性、工具和最佳实践过程中积累的心得体会。下面,我们将根据这个主题,探讨一些关键的Java并发编程知识点。 1. **线程与进程**:在多任务环境中,线程是...
Java并发编程是Java开发中必不可少的一部分,涉及到多线程、同步机制、线程池以及并发工具类等多个核心知识点。以下是对这些主题的详细说明: 1. **线程安全与锁 Synchronized 底层实现原理**: 线程安全是指在多...
### Java并发编程学习笔记知识点详解 #### 一、Java并发编程概述 Java并发编程是指在Java应用程序中同时执行多个操作的技术。它通过多线程、线程池等机制实现资源的有效利用,提高程序运行效率。Java并发编程的...
Java并发编程学习笔记,研究JAVA并发多线程编程的一本教程,使用并发技术可以开发出并行算法,充分利用多处理器的计算能力,避免硬件资源浪费。目前,在JAVA并发编程方面的论述系统且内容详实的技术资料不太多,Java...
### Java并发编程实践笔记知识点详解 #### 一、保证线程安全的方法 1. **不要跨线程访问共享变量:** 当多个线程共享某个变量时,若其中一个线程修改了该变量,其他线程若没有正确同步,则可能读取到错误的数据。...
"JUC并发编程学习笔记(硅谷)"很可能包含了关于Java并发工具集(Java Util Concurrency, JUC)的深入理解和实战经验。JUC是Java标准库提供的一套强大的并发处理工具,它极大地简化了多线程编程,提高了程序的可读性...
Java并发编程是Java开发中的重要领域,它涉及到多线程、同步、锁机制、线程池等关键概念,是提高程序性能和效率的关键技术。在Java中,并发编程的运用可以充分利用多核处理器的能力,实现高效的多任务处理。以下是对...
本文将基于文档《Java并发编程与高并发解决方案-学习笔记***.pdf》中提供的内容,来详细阐述并发编程和高并发的基本概念、CPU多级缓存与缓存一致性、以及Java内存模型。 ### 并发与高并发概念 在现代多线程编程中...
Java并发编程系列心得笔记,可以参考,欢迎共同交流学习
标题“多线程与高并发编程笔记、源码等”表明了资源的核心内容,涵盖了多线程和高并发编程的理论与实践。多线程允许一个应用程序同时执行多个任务,而高并发则指系统能够处理大量并发请求的能力。这两个概念在现代...
Java并发编程 背景介绍 并发历史 必要性 进程 资源分配的最小单位 线程 CPU调度的最小单位 线程的优势 (1)如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率 ...
通过阅读"Go语言学习笔记",你可以建立起对Go语言全面的认知,然后借助"Go并发编程实战"来深化对并发编程的理解,结合实际编写示例程序,将理论知识转化为实践经验。 在学习过程中,建议先从基础语法开始,掌握变量...
综上所述,这一系列学习笔记涵盖了并发编程的关键概念和实战技巧,包括Java内存模型、线程池、并发容器的使用以及常见数据结构的线程安全问题。通过深入学习这些内容,开发者可以更好地理解和解决多线程环境下的编程...
Java并发编程与高并发解决方案是开发高性能应用的关键技术。在基础篇中,主要涉及以下几个重要知识点: 1. **并发编程基础** - **并发**:并发是指在一个时间段内,多个线程交替执行,使得系统看起来像是同时处理...
java并发编程与并发解决方案是自己多年开发和学习的笔记,有助于(ˇˍˇ) 想~进一步提高的java开发工程师或架构师深入的学习java架构并发处理。同时,它也是 在实际工作中多年高并发解决方案和经验的总结
并发编程与高并发解决方案的学习笔记中,首先对并发与高并发进行了基本概念的介绍。并发指的是同时存在多个执行单元,但并不一定同时发生;而高并发是指系统能够同时处理很多的请求,这对于互联网分布式系统架构设计...
01-并发编程之深入理解JMM&并发三大特性(一)-fox 02-并发编程之深入理解JMM&并发三大特性(二)-fox 03-01-HashMap源码解析-monkey 03-并发List、Set、 ConcurrentHashMap底层原理剖析-monkey 04-Java并发线程池...