在 Java 中如何同步 hashmap 和 ConcurrentHashMap。

Java HashMap 默认不同步。
如果我们在多个线程添加和删除键值对的并发应用程序中从 HashMap 添加/删除键值对,我们最终可能会导致映射状态不一致。

同步HashMap - ConcurrentHashMap

如果我们希望在并发环境中使用 Map,我们的首选应该始终是使用 ConcurrentHashMap类。
ConcurrentHashMap通过设计支持并发访问它的键值对。
我们不需要执行任何另外的代码修改来启用地图同步。

请注意,从 ConcurrentHashMap获得的迭代器不会抛出 ConcurrentModificationException
然而,迭代器被设计为一次只能被一个线程使用。
这意味着我们从 ConcurrentHashMap 获得的每个迭代器都设计为由单个线程使用,不应传递。

如果我们这样做,则不能保证一个线程会看到另一个线程执行的映射更改(无需从映射中获取新的迭代器)。
迭代器保证在创建时反映地图的状态。

示例:

import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
public class HashMapExample 
{
    public static void main(String[] args) throws CloneNotSupportedException 
    {
        ConcurrentHashMap<Integer, String> concurrHashMap = new ConcurrentHashMap<>();

        //Put require no synchronization
        concurrHashMap.put(1, "A");
        concurrHashMap.put(2, "B");

        //Get require no synchronization
        concurrHashMap.get(1);

        Iterator<Integer> itr = concurrHashMap.keySet().iterator();

        //Using synchronized block is advisable
        synchronized (concurrHashMap) 
        {
            while(itr.hasNext()) {
                System.out.println(concurrHashMap.get(itr.next()));
            }
        }
    }
}

输出:

A
B
on  It Road.com

同步HashMap - Collections.synchronizedMap()

Synchronized HashMap 的工作方式也与 ConcurrentHashMap 非常相似,但几乎没有区别。

SynchronizedHashMap一次只允许一个线程执行读/写操作,因为它的所有方法都声明为 synchronized 。
ConcurrentHashMap允许多个线程在映射中的不同段上独立工作。
这允许 ConcurrentHashMap 中更高程度的并发,从而提高整个应用程序的性能。

两个类的迭代器都应该在synchronized块中使用,但是来自 SynchronizedHashMap 的迭代器是快速失败的。
ConcurrentHashMap 迭代器不是快速失败的。

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class HashMapExample 
{
    public static void main(String[] args) throws CloneNotSupportedException 
    {
        Map<Integer, String> syncHashMap = Collections.synchronizedMap(new HashMap<>());

        //Put require no synchronization
        syncHashMap.put(1, "A");
        syncHashMap.put(2, "B");

        //Get require no synchronization
        syncHashMap.get(1);

        Iterator<Integer> itr = syncHashMap.keySet().iterator();

        //Using synchronized block is advisable
        synchronized (syncHashMap) 
        {
            while(itr.hasNext()) {
                System.out.println(syncHashMap.get(itr.next()));
            }
        }
    }
}

输出:

A
B
日期:2020-09-17 00:09:27 来源:oir作者:oir