ConcurrentHashMap详解

ConcurrentHashMap

(使用场景 :系统配置类或者做成缓存Map)

ConcurrentHashMap的特点:

ConcurrentHashMap允许一边更新、一边遍历,也就是说在Iterator对象遍历的时候,

ConcurrentHashMap也可以进行remove,put操作,且遍历的数据会随着remove,put操作产出变化,也就是说在Iterator对象遍历的时候,ConcurrentHashMap也可以进行remove,put操作,且遍历的数据会随着remove,put操作产出变化

它只对put,remove操作使用了同步操作,get操作并不影响

 

举例:

一个线程对ConcurrentHashMap增加数据,另外一个线程在遍历时就能获得。


import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
/**
 *
 * ConcurrentHashMap只对put,remove操作使用了同步操作,get操作并不影响
 * **/
public class test1 {
       static Map<Long, String> conMap = new ConcurrentHashMap<Long, String>();
    public static void main(String[] args) throws InterruptedException {
        for (long i = 0; i < 5; i++) {
            conMap.put(i, i + "");
        }
        System.out.println("-----主线程添加数据--------");
        Thread thread = new Thread(new Runnable() {
            public void run() {
                conMap.put(100l, "100");
                System.out.println("线程1----添加数据:" + 100);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread thread2 = new Thread(new Runnable() {
            public void run() {
              //使用迭代器遍历数据
                for (Iterator<Entry<Long, String>> iterator = conMap.entrySet().iterator(); iterator.hasNext();) {
                    Entry<Long, String> entry = iterator.next();
                    System.out.println("线程2遍历数据----"+entry.getKey() + " - " + entry.getValue());
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        thread.start();
        thread2.start();
        Thread.sleep(3000);
        System.out.println("---------------主线程-------------------------");
        for (Entry<Long, String> entry : conMap.entrySet()) {
            System.out.println("主线程遍历所有的数据"+entry.getKey() + " " + entry.getValue());
        }
    }
}

效果:

ConcurrentHashMap详解


ConcurrentHashMap 中的putIfAbsent方法的使用以及返回值的含义

putIfAbsent方法的特点:

putIfAbsent方法主要是在向ConcurrentHashMap中添加键—值对的时候,它会先判断该键值对是否已经存在。如果不存在(新的entry),那么会向map中添加该键值对,并返回null。

如果已经存在,那么不会覆盖已有的值,直接返回已经存在的值。

举例:

import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
public class test2 {
       private static Map<String, Object> conMap = new ConcurrentHashMap<String, Object>();
       public static void main(String[] args) throws InterruptedException {
              conMap.put("yzy", 10010);
              System.out.println("--------添加key值(yzy)-------");
              Object putIfAbsent = ((ConcurrentHashMap<String, Object>) conMap).putIfAbsent("yzy",10086);
              System.out.println("删除key值前返回:"+putIfAbsent+",当前value值:"+conMap.get("yzy"));
              System.out.println("------------删除key值(yzy)后-----------------");
              conMap.remove("yzy");
              Object putIfAbsentSc = ((ConcurrentHashMap<String, Object>) conMap).putIfAbsent("yzy",10086);
              System.out.println("删除key值后返回:"+putIfAbsentSc+",当前value值:"+conMap.get("yzy"));
              
              Thread.sleep(3000);
              System.out.println("------------------------------------------------");
              for (Entry<String, Object> entry : conMap.entrySet()) {
            System.out.println("遍历所有的数据:  key值:"+entry.getKey() + " --- value值:" + entry.getValue());
        }
       }
}

效果:

ConcurrentHashMap详解