Java多线程-并发容器
2015-12-01 00:00
393 查看
摘要: Java多线程-并发容器
1、ConCurrentHashMap 来替代同步的HashMap 实现
2、CopyOnWriteArrayList 是List的同步实现
3、Queue 和 BlockQueue 接口
4、ConCurrentLinkedQueue 一个并发优先级的队列注意: java6中加入ConCurrentSkipListMap 和 ConCurrentSkipListSet 用来作为同步的SortedMap 和SortedSet ..
二、ConCurrentHashMap
我们都知道同步容器类每当执行一个操作的时候都会持有一个锁,如果同步容器中非常大,比如遍历查找是否存某个对象,消耗时间非常长,但是这段时间不允许其他线程访问这个容器,这是一种糟糕是事情。 [b][b]下载地址[/b][/b] ConCurrentHashMap 和HashMap 一样都是一个hash表,但是ConCurrentHashMap与HashMap完全使用不同的锁策略。它可以提供更好的并发性和伸缩性。在ConCurrentHashMap之前,是使用共用一个锁,进行同步每一个方法。并且严格的限制只有一个线程能同时访问容器;而ConcurrentHashMap 使用了更加细粒度的锁,-分离锁( 详情:ReentrantLock)这个锁机制允许更深层的共享访问,任何多线程可以并发的读操作访问此容器,当且仅当只用一个线程可以进行写容器操作。这样读线程和写线程都可以并发的访问容器大大提高了吞吐量,也没有怎么损失单线程的性能。但是,在应用的需求是线程独占访问枷锁的时候,ConCurrentMap是无法胜任的。
三、CopyOnWriteArrayList
CopyOnWriteArrayList 是 List容器的并发容器的替代品,通常它提供了更好的并发性,避免在容器迭代时候进行加锁和复制。下面是一段源代码
Java代码
public E set(int index, E element) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
E oldValue = get(elements, index);
if (oldValue != element) {
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len);
newElements[index] = element;
setArray(newElements);
} else {
// Not quite a no-op; ensures volatile write semantics
setArray(elements);
}
return oldValue;
} finally {
lock.unlock();
}
}
在操作之前:lock.lock(); 然后 lock.unlock(); 释放
Java代码
/**
* {@inheritDoc}
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get(int index) {
return get(getArray(), index);
}
读取不会加锁和释放锁操作。
Java多线程-并发容器
在Java1.5之后,通过几个并发容器类来改进同步容器类,同步容器类是通过将容器的状态串行访问,从而实现它们的线程安全的,这样做会消弱了并发性,当多个线程并发的竞争容器锁的时候,吞吐量会下降。那并发容器是为多线程并发而设计的。那么java1.5中添加了哪些并发容器?1、ConCurrentHashMap 来替代同步的HashMap 实现
2、CopyOnWriteArrayList 是List的同步实现
3、Queue 和 BlockQueue 接口
4、ConCurrentLinkedQueue 一个并发优先级的队列注意: java6中加入ConCurrentSkipListMap 和 ConCurrentSkipListSet 用来作为同步的SortedMap 和SortedSet ..
二、ConCurrentHashMap
我们都知道同步容器类每当执行一个操作的时候都会持有一个锁,如果同步容器中非常大,比如遍历查找是否存某个对象,消耗时间非常长,但是这段时间不允许其他线程访问这个容器,这是一种糟糕是事情。 [b][b]下载地址[/b][/b] ConCurrentHashMap 和HashMap 一样都是一个hash表,但是ConCurrentHashMap与HashMap完全使用不同的锁策略。它可以提供更好的并发性和伸缩性。在ConCurrentHashMap之前,是使用共用一个锁,进行同步每一个方法。并且严格的限制只有一个线程能同时访问容器;而ConcurrentHashMap 使用了更加细粒度的锁,-分离锁( 详情:ReentrantLock)这个锁机制允许更深层的共享访问,任何多线程可以并发的读操作访问此容器,当且仅当只用一个线程可以进行写容器操作。这样读线程和写线程都可以并发的访问容器大大提高了吞吐量,也没有怎么损失单线程的性能。但是,在应用的需求是线程独占访问枷锁的时候,ConCurrentMap是无法胜任的。
三、CopyOnWriteArrayList
CopyOnWriteArrayList 是 List容器的并发容器的替代品,通常它提供了更好的并发性,避免在容器迭代时候进行加锁和复制。下面是一段源代码
Java代码
public E set(int index, E element) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
E oldValue = get(elements, index);
if (oldValue != element) {
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len);
newElements[index] = element;
setArray(newElements);
} else {
// Not quite a no-op; ensures volatile write semantics
setArray(elements);
}
return oldValue;
} finally {
lock.unlock();
}
}
public E set(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); E oldValue = get(elements, index); if (oldValue != element) { int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len); newElements[index] = element; setArray(newElements); } else { // Not quite a no-op; ensures volatile write semantics setArray(elements); } return oldValue; } finally { lock.unlock(); } }
在操作之前:lock.lock(); 然后 lock.unlock(); 释放
Java代码
/**
* {@inheritDoc}
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get(int index) {
return get(getArray(), index);
}
/** * {@inheritDoc} * * @throws IndexOutOfBoundsException {@inheritDoc} */ public E get(int index) { return get(getArray(), index); }
读取不会加锁和释放锁操作。
相关文章推荐
- java多线程编程制作电子时钟
- java多线程入门知识及示例程序
- 使用java实现http多线程断点下载文件(一)
- 使用java实现http多线程断点下载文件(二)
- java多线程核心概念
- Java线程:大总结
- Java多线程初学者指南(1):线程简介
- Java.多线程(学习笔记)
- Java程序员面试中的多线程问题
- Java多线程1——概述
- Java多线程2——synchronized和Lock
- Java多线程3——如何停止线程
- java多线程
- java sleep wait join与interrupt的关系
- java多线程学习——CyclicBarrier
- java 多线程
- java 多线程的互斥代码
- JAVA多线程总结
- 黑马程序员-java多线程
- Java多线程共享变量控制