https://blog.csdn.net/silyvin/article/details/79407034
网上只搜到这个,看不懂~~~没说清 why
1
c4f36e5766583218 OP 比如为啥不像```java. util.ArrayList```涨 1.5 倍这样?
|
2
BBCCBB 2019-04-08 15:52:39 +08:00
每次 Write 时都要 Copy, 除了 addAll 这种 add 多个的, 没必要+n。 扩容+n,多的那部分用不到。
|
3
joshryo 2019-04-08 16:36:17 +08:00
这个集合在 add 动作前都会拷贝一份原集合,并在原集合的基础上+1,多出来的一个就是为了放置新的那个元素...addAll 的时候就不是+1 了
|
4
c4f36e5766583218 OP @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 的并发? |
5
BBCCBB 2019-04-08 17:08:01 +08:00 1
。。。
照你说的,现在是 16,扩容 1.5 倍就是 24, 但是现在只是添加一个元素,size=17, 那 24-17=7 个元素就被浪费掉了,根本用不到,因为下次执行修改操作的时候这个数组就没用了,会新分配一个数组,将原数组的数据拷贝过来 |
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 损失的性能来的更多。 归根结底,还得看应用场景 |
7
geelaw 2019-04-08 17:41:38 +08:00 via iPhone 2
COWAL 是只读数组,所以不需要有任何多余的容量。
|
8
c4f36e5766583218 OP @BBCCBB #5 哦,对对,我想错了,是你说的```会新分配一个数组```
此贴终结。。。 |