您的位置:首页 > 编程语言 > Java开发

Java基础-Map容器的并发访问控制

2016-02-15 23:00 357 查看
        在并发环境中,多线程之间共享数据时,需要对数据访问进行并发控制。例如,经典的生产者-消费者的实例中,生产线程和消费线程共享同一个容器对象,那么必须使用线程安全的容器对象。

        简单的使用HashMap,存储信息后,统计某些key的出现次数,正确的并发控制代码如下:

import java.util.HashMap;

public class SharedMap {
private HashMap<String,Integer> map = new HashMap<>();

public synchronized void add(String key){
Integer value = map.get(key);
if(value==null){
map.put(key, 1);
}else{
map.put(key, value+1);
}
}

}

        由于并发环境下,对map对象的访问操作中,get和put是一起的原子操作,所以最简单的就是使用内置锁进行同步控制。java并发包中还有一个适用于并发环境下的高效的容器类ConcurrentHashMap,这个类中没有对整个Map加锁独占访问的支持,它使用了一种更细粒度的加锁机制即分段锁。由于每个bucket桶元素都对应一个段锁,所以大并发环境下能允许一定数量的线程并发第put数据(因为不同的key来说,put操作使用的都是对应的段锁,它们的段锁匙不同的,所以不容易造成阻塞等待)。所以,在并发环境下,这个类更容易实现高效的吞吐量。

        那么上述代码如果使用ConcurrentHashMap的话,该如何修改呢?如果直接去掉synchronized的话,这段并发控制的代码存在什么问题呢?因为ConcurrentHashMap类并不能保证原子性,而上述代码的方法体所有语句都应该是一个子则操作,所以即使是换成这个类型,也还是需要加锁的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: