• CopyOnWrite


    1. 读多写少的场景引发的问题?

      读写互斥,在写的过程中,大量的读操作阻塞,无法执行。

    2. CopyOnWrite的思想来解决(参考JDK里的 CopyOnWriteArrayList 的源码)

      原数据用于读操作,原数据的拷贝副本用于写操作,副本写完马上赋值给原数据,使用volatile关键字。

    // 这个数组是核心的,因为用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();
        }
    }
    final void setArray(Object[] a) {
        array = a;
    }

    3. 在kafka中的应用,内存缓冲用到的数据结构

    private final ConcurrentMap<TopicPartition, Deque<RecordBatch>> batches = new CopyOnWriteMap<TopicPartition, Deque<RecordBatch>>();
     // 典型的volatile修饰普通Map
        private volatile Map<K, V> map;
        @Override
        public synchronized V put(K k, V v) {
            // 更新的时候先创建副本,更新副本,然后对volatile变量赋值写回去
            Map<K, V> copy = new HashMap<K, V>(this.map);
            V prev = copy.put(k, v);
            this.map = Collections.unmodifiableMap(copy);
            return prev;
        }
        @Override
        public V get(Object k) {
            // 读取的时候直接读volatile变量引用的map数据结构,无需锁
            return map.get(k);
        }
    转载出处
    作者:石杉的架构笔记
    链接:https://juejin.im/post/5cd1724cf265da03a7440aae
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    os.environ()详解
    查看django setting 源码
    FBV or CBV django settings 源码 模板层语法 摸板的继承 摸板的导入
    jq
    centos安装docker
    idea mapper报红解决
    Method has too many Body parameters
    Gradle安装配置
    itext生成PDF报错java.io.IOException: The document has no pages
    数字千分位
  • 原文地址:https://www.cnblogs.com/yangjiming/p/11009647.html
Copyright © 2020-2023  润新知