zoukankan      html  css  js  c++  java
  • 3.ConcurrentHashMap 锁分段机制 Copy-On-Write

    /*ConcurrentHashMap*/

    Java 5.0 在 java.util.concurrent 包中提供了 多种 并发容器来改进同步容器的性能

    ConcurrentHashMap 同步容器类 是 Java5 增加的一个线程安全的 哈希表。对于多线程的操作,介于HashMap 与 HashTable 之间

      HashMap 是线程不安全的,不支持并发操作

      HashTable 是线程安全的,采用的独占锁,即一次只能有一个线程对容器进行操作

      HashTable 还有一个问题,当执行一些复合操作,如:若存在,则删除,  if(!table.contans()) { table.put() } ,同样可能出现线程问题

    ConcurrentHashMap 介于 HashMap 与 Hashtable 之间。内部采用 “锁分段”机制替代Hashtable的独占锁。进而提高性能(在jdk1.8之后,底层就不采用锁分段的方式了,而是采用CAS算法)

    锁分段:

      有一个concurrentLevel(分段级别)(默认的级别为16),将锁分成16段,每个段都是一个独立的锁,每段锁会有16(默认)个Entry

      当有多个线程并发访问时,可以访问不同的段,实现了并行, 提高了效率,并且提供了一些复合操作的方法

    /*其他并发容器类*/

    JUC 还提供了其他用于多线程上下文中Collection 实现(以前只能 用synchronize 来同步这些集合的方法,实现同步):

    ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet、CopyOnWriteArrayList 和 CopyOnWriteArraySet

      1.当期望许多线程访问一个 给定collection 时,ConcurrentHashMap通常优于同步的HashMap

      2.ConcurrentSkipListMap 通常优于同步的TreeMap。

      3.当期望的读数 和 遍历 远远大于列表的更新数时,CopyOnWriteArrayList优于同步的ArrayList,

      但是 CopyOnWriteArrayList 因为每次更新都会进行复制,开销非常大,并发迭代操作多时可以选择

     1 /*
     2  * CopyOnWriteArrayList /CopyOnWriteArraySet : "写入并复制"
     3  * Copy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,
     4  *
     5  * 从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略。
     6  * 
     7  * 当出现并发,多个线程想对这个内容进行操作,读操作的时候,无所谓,读的都是同一份,也不会加锁;;
     8  * 写操作的时候,为了避免修改同一份,采用的策略是,把内容Copy出去形成一个新的内容然后再改,以此来避免并发问题
     9  * 
    10  * 从JDK1.5开始Java并发包里提供了两个使用CopyOnWrite机制实现的并发容器,它们是CopyOnWriteArrayList和CopyOnWriteArraySet。
    11  * CopyOnWrite容器非常有用,可以在非常多的并发场景中使用到
    12  * 
    13  * 注意 :添加操作多时,效率低因为每次添加时都会将当前List复制一份,开销非常的大。并发迭代操作时可以选择
    14  * */
    15 public class TestCopyOnWriteArrayList {
    16     public static void main(String[] args) {
    17         ListThread lt = new ListThread();
    18         for(int i = 0;i<10;i++) {
    19             new Thread(lt).start();
    20         }
    21     }
    22 }
    23 
    24 class ListThread implements Runnable {
    25     //private static List<String> list = Collections.synchronizedList(new ArrayList<String>());  使用 这种同步的ArrayList,当遍历的时候进行 add 操作,就会报错
    26     private static CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
    27     static {
    28         list.add("1");
    29         list.add("2");
    30         list.add("3");
    31     }
    32     @Override
    33     public void run() {
    34         Iterator<String> iterator = list.iterator();
    35         while(iterator.hasNext()) {
    36             System.out.println(iterator.next());
    37             list.add("4");
    38         }
    39     }
    40     
    41 }
  • 相关阅读:
    iOS 时区问题总结 NSTimeZone
    项目中图片问题
    支付宝支付相关问题汇总
    算法时间计算:logA(N)与O(n)
    UE4 AR开发笔记
    UE4 PostProcessVolume笔记
    cpp typename关键字
    UE4 二维相关
    ATOM基础教程一使用前端插件emmet(16)
    监听浏览器返回上一页
  • 原文地址:https://www.cnblogs.com/xuzekun/p/7427229.html
Copyright © 2011-2022 走看看