当前位置:   article > 正文

Java-写时复制CopyOnWrite_java内存分配是写时复制吗

java内存分配是写时复制吗

介绍

写时复制(Copy-on-write,COW,奶牛)是一种计算机程序设计领域的优化策略。

核心思想

多个调用者读操作读指针指向的同一资源,只在调用者写时,复制一个资源的副本,写完后再用副本替换老资源。

应用

  1. Linux使用COW技术减少Fork开销;
  2. 文件系统通过COW技术一定程度上保证数据完整性;
  3. 数据库利用写时复制策略,为用户提供一份snapshot;
  4. JDK 的 CopyOnWriteArrayList 和 CopyOnWriteArraySet 也利用了COW技术。

Vector 和 Collections.SynchronizedXxx

ArrayList线程不安全,Vector 和 Collections.SynchronizedXxx 线程安全。

Vector通过在每个方法声明处都用synchronized关键字修饰来保证线程安全:
截图

Collections.SynchronizedXxx通过在每个方法内都用synchronized关键字封装具体操作来保证线程安全:
截图

但是,容器线程安全,并不意味着并发时可以放心大胆使用,也得注意使用方法,如:

public class CopyOnWriteTest {
   

    public static void main(String[] args) {
   
        Vector<Integer> vector = new Vector<>();
        vector.add(1);
        vector.add(2);
        vector.add(3);
        vector.add(4);
        vector.add(5);
        for (Integer item : vector) {
   
            new Thread(vector::clear).start();
            System.out.println(item);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

执行结果:

1
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.Vector$Itr.checkForComodification(Vector.java:1210)
    at java.util.Vector$Itr.next(Vector.java:1163)
    at com.wkw.study.copyonwrite.CopyOnWriteTest.main(CopyOnWriteTest.java:20)
  • 1
  • 2
  • 3
  • 4
  • 5

根本原因是Vector继承了AbstractList,而AbstractList维护了容器修改次数modCount,每次Vector修改时modCount都会加1,但是,Vector的迭代器:

/**
 * Returns an iterator over the elements in this list in proper sequence.
 *
 * <p>The returned iterator is <a href=" "><i>fail-fast</i></a >.
 *
 * @return an iterator over the elements in this list in proper sequence
 */
public synchronized Iterator<E> iterator() {
   
    return new Itr();
}

/**
 * An optimized version of AbstractList.Itr
 */
private class Itr implements Iterator<E> {
   
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;
    
    public E next() {
   
        synchronized (Vector.this) {
   
            checkForComodification();
            int i = cursor;
            if (i >= elementCount)
                throw new NoSuchElementException();
            cursor = i + 1;
            
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/821944
推荐阅读
相关标签
  

闽ICP备14008679号