zoukankan      html  css  js  c++  java
  • ConcurrentHashMap

    • Java 5.0 在java.util.concurrent 包中提供了多种并发容器类来改进同步容器的性能。
    • ConcurrentHashMap 同步容器类是Java 5 增加的一个线程安全的哈希表。对与多线程的操作,介于HashMap 与Hashtable 之间。内部采用“锁分段”机制替代Hashtable 的独占锁。进而提高性能。
    • 此包还提供了设计用于多线程上下文中的Collection 实现:ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet、CopyOnWriteArrayList 和CopyOnWriteArraySet。当期望许多线程访问一个给定collection 时,ConcurrentHashMap 通常优于同步的HashMap,ConcurrentSkipListMap 通常优于同步的TreeMap。当期望的读数和遍历远远大于列表的更新数时,CopyOnWriteArrayList 优于同步的ArrayList。

    HashMap与Hashtable 的底层是一样的,Hashtable是线程安全的,hashtable会给整个Hash表加上锁,导致运行效率非常低。使用Hashtable进行操作时,并没有达到并行的目的,相当于并行转串行。

    Hashtable还存在复合操作: 复合操作也是线程不安全的

      "若不存在则添加"

      "若存在则删除"

      if(table.contains()){

        //table.put()

      }

    ConcurrentHashMap 采用 "锁分段" 机制

      ConcurrentHashMap 中有一个级别 叫 ConcurrentLevel,默认级别为16

      即分为16个段,默认有16个段(Segment),每个段中有一个独立hash表,默认Hash表长度为16

      每个段都是一个独立的锁,这就意味着线程多个线程访问不同的段是互不干扰的,达到并行的目的

      

    CopyOnWriteArrayList

    package com.java.juc;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    
    public class TestCopyOnWriteArrayList {
    
        public static void main(String[] args) {
            HelloThread ht = new HelloThread();
            
            for(int i = 0;i<10;i++){
                new Thread(ht).start();
            }
            
        }
    
    }
    
    class HelloThread implements Runnable{
        private static List<String> list = new ArrayList<>();
        
        static{
            list.add("AA");
            list.add("BB");
            list.add("CC");
        }
        
        public void run() {
            Iterator<String> it = list.iterator();
            while(it.hasNext()){
                System.out.println(it.next());
            }
            
            list.add("DD");
        }
    }

    会出现如下问题:

    Exception in thread "Thread-9" Exception in thread "Thread-7" Exception in thread "Thread-5" java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
        at java.util.ArrayList$Itr.next(Unknown Source)
        at com.java.juc.HelloThread.run(TestCopyOnWriteArrayList.java:33)
        at java.lang.Thread.run(Unknown Source)
    java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
        at java.util.ArrayList$Itr.next(Unknown Source)
        at com.java.juc.HelloThread.run(TestCopyOnWriteArrayList.java:33)
        at java.lang.Thread.run(Unknown Source)
    java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
        at java.util.ArrayList$Itr.next(Unknown Source)
        at com.java.juc.HelloThread.run(TestCopyOnWriteArrayList.java:33)
        at java.lang.Thread.run(Unknown Source)
    Exception in thread "Thread-4" Exception in thread "Thread-0" Exception in thread "Thread-1" java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
        at java.util.ArrayList$Itr.next(Unknown Source)
        at com.java.juc.HelloThread.run(TestCopyOnWriteArrayList.java:33)
        at java.lang.Thread.run(Unknown Source)

    可以使用 CopyOnWriteArrayList 解决问题:

    package com.java.juc;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.concurrent.CopyOnWriteArrayList;
    
    
    public class TestCopyOnWriteArrayList {
    
        public static void main(String[] args) {
            HelloThread ht = new HelloThread();
            
            for(int i = 0;i<10;i++){
                new Thread(ht).start();
            }
            
        }
    
    }
    
    class HelloThread implements Runnable{
    //    private static List<String> list = new ArrayList<>();
        private static CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
        
        static{
            list.add("AA");
            list.add("BB");
            list.add("CC");
        }
        
        public void run() {
            Iterator<String> it = list.iterator();
            while(it.hasNext()){
                System.out.println(it.next());
            }
            
            list.add("DD");
        }
    }

    注意:添加操作多时,效率低,因为每次添加时都会进行复制,开销非常大。并发迭代操作多时可以选择。

  • 相关阅读:
    最大公约数
    面向对象(jianli)(游客买门票)
    String
    ATM模拟取款
    常用快捷键归纳
    购物清单
    jxls使用模版导出Excel
    IText 生成pdf,处理table cell列跨页缺失的问题
    Java使用IText(VM模版)导出PDF
    js ajax post提交 ie和火狐、谷歌提交的编码不一致,导致中文乱码
  • 原文地址:https://www.cnblogs.com/wq3435/p/6341731.html
Copyright © 2011-2022 走看看