本文主要介绍Java中,SynchornizedMap和ConcurrentHashMap使用的方法和使用示例代码,以及它们之间的区别。

1、SynchornizedMap(Map)使用示例代码

HashMap是一个非同步的collection类。如果需要对其执行线程安全操作,则必须显式同步它。可以使用使用Collections.synchronizedMap(hashmap)进行同步。

1) SynchornizedMap使用语法

Map map = Collections.synchronizedMap(new HashMap());
//这不需要在同步块中
Set set = map.keySet();
// 在map上同步,不是在set上
synchronized (map) {  
      // 迭代器必须在同步块中
      Iterator iterator = set.iterator(); 
      while (iterator.hasNext()){
          ...
      }
}

2) 使用示例代码

package beginnersbook.com;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Iterator;
public class HashMapSyncExample {
    public static void main(String args[]) {
         HashMap<Integer, String> hmap= new HashMap<Integer, String>();
         hmap.put(11, "cjavapy");
         hmap.put(22, "java");
         hmap.put(33, "python");
         hmap.put(44, "c#");
         hmap.put(88, "linux");
         Map map= Collections.synchronizedMap(hmap);
         Set set = map.entrySet();
         synchronized(map){
             Iterator i = set.iterator();
             // 显示元素
             while(i.hasNext()) {
                Map.Entry me = (Map.Entry)i.next();
                System.out.print(me.getKey() + ": ");
                System.out.println(me.getValue());
             }
         }
    }
}

2、ConcurrentHashMap使用示例代码

ConcurrentHashMap是线程安全的,使用锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。与并发环境中的Hashtable相比,它速度更快且具有更好的性能。

package com.concretepage;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ConcurrentHashMapDemo {
      private final ConcurrentHashMap<Integer,String> conHashMap = new ConcurrentHashMap<Integer,String>();
	  public static void main(String[] args) {
		  ExecutorService  service = Executors.newFixedThreadPool(3);
		  ConcurrentHashMapDemo ob = new ConcurrentHashMapDemo();
		  service.execute(ob.new WriteThreasOne());
		  service.execute(ob.new WriteThreasTwo());
		  service.execute(ob.new ReadThread());
		  service.shutdownNow();
	  }
	  class WriteThreasOne implements Runnable {
		@Override
		public void run() {
			for(int i= 1; i<=10; i++) {
				conHashMap.putIfAbsent(i, "A"+ i);
			}			
		}
	  }
	  class WriteThreasTwo implements Runnable {
		@Override
		public void run() {
			for(int i= 1; i<=5; i++) {
				conHashMap.put(i, "B"+ i);
			}
		}
	  }  
	  class ReadThread implements Runnable {
		@Override
		public void run() {
		   Iterator<Integer> ite = conHashMap.keySet().iterator();
	  	   while(ite.hasNext()){
	  		   Integer key = ite.next();
	  		   System.out.println(key+" : " + conHashMap.get(key));
		  }
		}
	  }	  
} 

3、SynchornizedMap(Map)和ConcurrentHashMap区别

SynchornizedMap是一个方法,HashMap本身非线程安全的,但是当使用 Collections.synchronizedMap(new HashMap()) 进行包装后就返回一个线程安全的Map。

ConcurrentHashMap是Java 1.5中Hashtable的替代品,是并发包的一部分。使用ConcurrentHashMap,不仅可以在并发多线程环境中安全地使用它,而且还提供比HashtableSynchornizedMap更好的性能,这是一个更好的选择。ConcurrentHashMap性能更好,因为它锁定了Map的一部分。它允许并发的读操作,同时通过同步写操作保持完整性。