Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ConcurrentHashMap与同步HashMap_Java_Core - Fatal编程技术网

Java ConcurrentHashMap与同步HashMap

Java ConcurrentHashMap与同步HashMap,java,core,Java,Core,在HashMap上使用包装类SynchronizedMap,与ConcurrentHashMap有什么区别 它只是能够在迭代时修改HashMap(ConcurrentHashMap)?简单回答: 这两个映射都是Map接口的线程安全实现ConcurrentHashMap是为了在需要高并发性的情况下实现更高的吞吐量而实现的 Brian Goetz关于ConcurrentHashMap背后的想法的书读得非常好。强烈推荐。ConcurrentHashMap是线程安全的,无需同步整个映射。当使用锁进行写操

HashMap
上使用包装类
SynchronizedMap
,与
ConcurrentHashMap
有什么区别

它只是能够在迭代时修改
HashMap
ConcurrentHashMap
)?

简单回答:

这两个映射都是
Map
接口的线程安全实现
ConcurrentHashMap
是为了在需要高并发性的情况下实现更高的吞吐量而实现的


Brian Goetz关于
ConcurrentHashMap
背后的想法的书读得非常好。强烈推荐。

ConcurrentHashMap是线程安全的,无需同步整个映射。当使用锁进行写操作时,读取可以非常快地进行。

ConcurrentHashMap
使用称为
锁剥离的细粒度锁定机制,以允许更大程度的共享访问。因此,它提供了更好的并发性和可伸缩性


另外,为
ConcurrentHashMap
返回的迭代器是弱一致的,而不是同步HashMap使用的快速失败技术

Synchronized
HashMap

  • 每个方法都使用对象级锁进行同步。因此,synchMap上的get和put方法获得一个锁

  • 锁定整个集合是一项性能开销。当一个线程持有锁时,没有其他线程可以使用该集合


  • ConcurrentHashMap
    是在JDK5中引入的

  • 在对象级别没有锁定,锁定的粒度要细得多。对于
    ConcurrentHashMap
    ,锁可能位于hashmap存储桶级别

  • 较低级别锁定的效果是,您可以同时拥有读写器,这对于同步集合是不可能的。这将带来更大的可伸缩性


  • ConcurrentHashMap
    如果一个线程试图修改它,而另一个线程在其上迭代,则不会抛出
    ConcurrentModificationException


  • 这篇文章读得很好。强烈推荐。

    同步地图上的方法持有对象上的锁,而在
    ConcurrentHashMap
    中有一个“锁条带化”的概念,即锁被持有在内容的存储桶上。从而提高了可伸缩性和性能

    ConcurrentHashMap:

    1) 这两个映射都是映射接口的线程安全实现

    2) ConcurrentHashMap的实现是为了在需要高并发性的情况下获得更高的吞吐量

    3) 对象级别中没有锁定

    同步哈希映射:


    1) 每个方法都使用对象级锁进行同步

    两者都是HashMap的同步版本,其核心功能和内部结构有所不同

    ConcurrentHashMap由内部段组成,这些段在概念上可以看作是独立的HashMap。 在高并发执行中,所有这些段都可以由单独的线程锁定。 因此,多个线程可以从ConcurrentHashMap获取/放置键值对,而无需彼此阻塞/等待。 这是为了提高吞吐量而实现的

    鉴于


    Collections.synchronizedMap(),我们得到了HashMap的一个同步版本,它是以阻塞方式访问的。这意味着,如果多个线程试图同时访问synchronizedMap,则允许它们以同步方式一次获取/放置一个键值对。

    我们可以通过同时使用ConcurrentHashMap和SynchronizedHashMap来实现线程安全。但是如果你看看他们的架构,就会发现有很多不同

  • 同步hashmap
  • 它将在对象级别保持锁定。因此,如果您想执行任何操作,如put/get,则必须首先获取锁。同时,不允许其他线程执行任何操作。因此,一次只能有一个线程对此进行操作。所以这里的等待时间会增加。与ConcurrentHashMap相比,我们可以说性能相对较低

  • ConcurrentHashMap
  • 它将在段级别保持锁定。它有16个段,默认情况下将并发级别保持为16。因此,一次可以有16个线程在ConcurrentHashMap上运行。此外,读取操作不需要锁。因此,任意数量的线程都可以对其执行get操作

    如果thread1希望在段2中执行put操作,thread2希望在段4上执行put操作,则此处允许。意味着,16个线程一次可以对ConcurrentHashMap执行更新(put/delete)操作

    这样这里的等待时间就少了。因此,性能相对优于SynchronizedHashMap

    ConcurrentHashMap允许并发访问数据。整个地图分为若干部分

    读取操作即
    get(对象键)
    即使在段级别也不同步

    但是写入操作,即删除(对象密钥)、获取(对象密钥)
    在段级别获取锁。只有整个映射的一部分被锁定,其他线程仍然可以从不同的段读取值,除了锁定的段

    同步地图另一方面,在对象级别获取锁。所有线程都应该等待当前线程,而不考虑操作(读/写)。

    根据java文档

    Hashtable和Collections.synchronizedMap(新HashMap())是 同步的。但是ConcurrentHashMap是“并发的”

    并发集合是线程安全的,但不受单个排除锁的控制

    在ConcurrentHashMap的特殊情况下,它安全地允许 任意数量的并发读取以及可调数量o
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    public class Ex_ConcurrentHashMap {
    
        public static void main(String[] args) {
            
            Map<String, String> map = new ConcurrentHashMap<>();
            map.put("one", "one");
            map.put("two", "two");
            map.put("three", "three");
            System.out.println("1st  map : "+map);
            String key = null;
            for(Map.Entry<String, String> itr : map.entrySet())
            {
                key = itr.getKey();
                if("three".equals(key))
                {
                    map.put("FOUR", "FOUR");
                }
                System.out.println(key+" ::: "+itr.getValue());
            }
            System.out.println("2nd  map : "+map);
            //map.put("FIVE", null);//java.lang.NullPointerException
            map.put(null, "FIVE");//java.lang.NullPointerException
            System.out.println("3rd  map : "+map);
        }
    }
    
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    
    public class Ex_Synchronizedmap {
    
        public static void main(String[] args) {
            
            Map<String, String> map = new HashMap<>();
            
            map.put("one", "one");
            map.put("two", "two");
            map.put("three", "three");
            map.put("FOUR", null);
            map.put(null, "FIVE");
            
            System.out.println("map : "+map);
            
            Map<String, String> map1 = 
                    Collections.synchronizedMap(map);
            System.out.println("map1 : "+map1);
            
            String key = null;
            for(Map.Entry<String, String> itr : map1.entrySet())
            {
                key = itr.getKey();
                if("three".equals(key))
                {
                    map1.put("ABC", "ABC");
                }
                System.out.println(key+" ::: "+itr.getValue());
            }
            
            System.out.println("New Map :: "+map1);
            
            
            
            Iterator<Entry<String, String>> iterator = map1.entrySet().iterator();
            int i = 0;
            while(iterator.hasNext())
            {
                if(i == 1)
                {
                    map1.put("XYZ", "XYZ");
                }
                Entry<String, String> next = iterator.next();
                System.out.println(next.getKey()+" :: "+next.getValue());
                i++;
            }
        }
    
    }