zoukankan      html  css  js  c++  java
  • CopyOnWrite解析

    核心思想

    读写分离,空间换时间,避免为保证并发安全导致的激烈的锁竞争。

    关键点

    1、CopyOnWrite适用于读多写少的情况,最大程度的提高读的效率;
    2、CopyOnWrite是最终一致性,在写的过程中,原有的读的数据是不会发生更新的,只有新的读才能读到最新数据;
    3、如何使其他线程能够及时读到新的数据,需要使用volatile变量;
    4、写的时候不能并发写,需要对写操作进行加锁;

    源码解析

    CopyOnWriteArrayList 相对于 ArrayList 线程安全,底层通过复制数组的方式来实现,其核心概念就是: 数据读取时直接读取,不需要锁,数据写入时,需要锁,且对副本进行操作。那么当数据的操作以读取为主时,我们便可以省去大量的读锁带来的消耗。同时为了能让多线程操作List时,一个线程的修改能被另一个线程立马发现,CopyOnWriteList采用了Volatile关键词来进行修饰,即每次数据读取不从缓存里面读取,而是直接从数据的内存地址中读取。
    以CopyOnWriteArrayList 的add()操作为例来看

      // 这个数组是核心的,因为用volatile修饰了
      // 只要把最新的数组对他赋值,其他线程立马可以看到最新的数组
      private transient volatile Object[] array;
    
      public boolean add(E e) {
    
          final ReentrantLock lock = this.lock;
          lock.lock();
    
          try {
              Object[] elements = getArray();
              int len = elements.length;
    
              // 对数组拷贝一个副本出来
              Object[] newElements = Arrays.copyOf(elements, len + 1);
    
              // 对副本数组进行修改,比如在里面加入一个元素
              newElements[len] = e;
    
              // 然后把副本数组赋值给volatile修饰的变量
              setArray(newElements);
              return true;
    
    
          } finally {
              lock.unlock();
          }
      }
    

    结论

    总结而言,多线程实现COW实际上就是以空间换取时间使得数据读取时不需要锁。只是减少了读锁的开销,但与常规的多线程操作共享数据的本质没有什么区别。

    参考

    https://zhuanlan.zhihu.com/p/114547256
    https://cloud.tencent.com/developer/article/1821632
    https://blog.csdn.net/javageektech/article/details/108114252

  • 相关阅读:
    C# 保存文件到数据库
    4.Linq To Xml操作XML增删改查
    服务器端包含 SSI简介
    htm、html、shtml网页区别
    localStorage使用总结
    jquery.cookie.js——jquery的cookie插件
    javascript:;与javascript:void(0)使用介绍
    JS中函数void()
    gitlab使用 —— 多人协同工作(重要技能)
    cookie、localstroage与sessionstroage的一些优缺点
  • 原文地址:https://www.cnblogs.com/huangjianping/p/15060895.html
Copyright © 2011-2022 走看看