Java java.util.concurrent.ConcurrentHashMap的用法以及案例

Java编程 05/31 阅读 15 views次 人气 0
摘要:

ConcurrentHashMap随java.util.concurrent包一起引入JDK1.5中,主要为了解决HashMap线程不安全和Hashtable效率不高的问题,它融合了Hashtable和HashMap二者的优势。

HashMap不是线程安全,可能在并发情况下发生以下问题:

1、数据丢失,如果多个线程同时put相同的key时,那么其中一个线程的数据将会丢失或get不到了。

2、Map.size()与实际不合,多线程环境下put的HashMap会被“损坏”,其中会造成size与实际不符合。

3、导致死循环,当HashMap在做动态扩容是,需要对整个Hash表里的无素都需要被重算一遍。这叫rehash,并发环境下的rehash过程可能会带来循环链表,导致死循环致使线程挂掉。

为了解决以上的问题JDK提供了2个线程安全的HashMap:HashTable和ConcurrentHashMap:

1、HashTable 底层使用了synchronized,对所有的方法增加了锁,就解决了并发问题,但同时降低了效率。

2、为了解决效率问题,JDK又提供了一个既能保持线程安全,有可以解决效率问题的工具类ConcurrentHashMap。


ConcurrentHashMap原理:分段锁

1、HashTable容器在竞争激烈的并发环境下表现出效率低下的原因,是因为所有访问HashTable的线程都必须竞争同一把锁,那假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。

2、简单的说就是把数组问题多个段,每个段各有一把锁。JDK1.8后则改为每个数组的元素一个锁


实例代码:

package com.what21;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapMain {
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Map<String, String> map = new ConcurrentHashMap<String, String>();
		map.put("1", "1");
		map.put("2", "2");
		map.put("3", "3");
		map.put("4", "4");
		// map.keySet().iterator();
		Iterator<String> it = map.keySet().iterator();

		while (it.hasNext()) {
			String key = it.next();
			System.out.println(key + ","+ map.get(key));
			if (key.equals("3")) {
				map.put(key + "key", "3");
			}

		}
	}
 
}


评论

表情

分享到: