V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
c4f36e5766583218
V2EX  ›  Java

CopyOnWriteArrayList 扩容为什么只+1?

  •  
  •   c4f36e5766583218 · 2019-04-08 15:42:50 +08:00 · 2478 次点击
    这是一个创建于 1835 天前的主题,其中的信息可能已经有所发展或是发生改变。

    https://blog.csdn.net/silyvin/article/details/79407034

    网上只搜到这个,看不懂~~~没说清 why

    8 条回复    2019-04-08 20:04:35 +08:00
    c4f36e5766583218
        1
    c4f36e5766583218  
    OP
       2019-04-08 15:51:51 +08:00
    比如为啥不像```java. util.ArrayList```涨 1.5 倍这样?
    BBCCBB
        2
    BBCCBB  
       2019-04-08 15:52:39 +08:00
    每次 Write 时都要 Copy, 除了 addAll 这种 add 多个的, 没必要+n。 扩容+n,多的那部分用不到。
    joshryo
        3
    joshryo  
       2019-04-08 16:36:17 +08:00
    这个集合在 add 动作前都会拷贝一份原集合,并在原集合的基础上+1,多出来的一个就是为了放置新的那个元素...addAll 的时候就不是+1 了
    c4f36e5766583218
        4
    c4f36e5766583218  
    OP
       2019-04-08 17:04:58 +08:00
    @BBCCBB #2
    @joshryo #3
    java.util.concurrent.CopyOnWriteArrayList#add(E),就拿这个方法来说(为什么不按 ArrayList 原理实现?)
    .add("a") // 内部判断```Object[] array```是否够放,不够放就扩容 1.5 倍( copy 了)
    .add("b") // ```Object[] array```够放了(不用 copy ),直接在对应的 index 处设值
    ------
    ArrayList 有
    ```transient Object[] elementData;```
    ```private int size;```
    通过 size 来标记 elementData 用到了哪个下标。。
    ------
    你俩说的,我还是没 get 到 why。
    会不会是 CopyOnWriteArrayList 内如果添加 size 字段,但没法保证 size 的并发?
    BBCCBB
        5
    BBCCBB  
       2019-04-08 17:08:01 +08:00   ❤️ 1
    。。。
    照你说的,现在是 16,扩容 1.5 倍就是 24, 但是现在只是添加一个元素,size=17, 那 24-17=7 个元素就被浪费掉了,根本用不到,因为下次执行修改操作的时候这个数组就没用了,会新分配一个数组,将原数组的数据拷贝过来
    hujianxin
        6
    hujianxin  
       2019-04-08 17:27:26 +08:00
    如果是单纯 add 的话,语意就是+1,为什么要 1.5 倍呢,关键是 add 与扩容不是一个概念

    话说回来,既然每次 add 都要扩容 1 了,就没有必要再另外进行 1.5 倍的扩容了。

    感觉 copyonwritearraylist 在牺牲一些 copy 过程的性能,来换取读写分离的方便。因为,如果你有两个线程,一个通过迭代器读,另一个写,这样会导致 ConcurrentModificationException,为了避免这个,普通 arraylist 需要对整个 list 加锁,这样损失的性能比 copy 损失的性能来的更多。

    归根结底,还得看应用场景
    geelaw
        7
    geelaw  
       2019-04-08 17:41:38 +08:00 via iPhone   ❤️ 2
    COWAL 是只读数组,所以不需要有任何多余的容量。
    c4f36e5766583218
        8
    c4f36e5766583218  
    OP
       2019-04-08 20:04:35 +08:00
    @BBCCBB #5 哦,对对,我想错了,是你说的```会新分配一个数组```
    此贴终结。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5418 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 09:20 · PVG 17:20 · LAX 02:20 · JFK 05:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.