理解Java中的CopyOnWriteArrayList

private E get(Object[] a, int index) {

return (E) a[index];

}

/**

  • {@inheritDoc}

  • @throws IndexOutOfBoundsException {@inheritDoc}

*/

public E get(int index) {

return get(getArray(), index);

}

2. 适用场景

因为每次写数据的时候都会开辟一个新的数组,这样就会耗费内存,而且加锁了,写的性能不是很好.而读操作是非常迅速的,并且还支持在写的同时可以读.

所以就非常适合读多写少的场景.

3. 缺点

  • 内存消耗大: 每次写操作都需要复制一个新的数组,所以内存占用是非常大的

  • 数据不一致: 读数据的时候可能读取到的不是最新的数据,因为可能部分写入的数据还未同步到读的数组中.

对内存敏感和实时性要求很高的场景都不适合.

4. CopyOnWriteArraySet

在翻阅CopyOnWriteArrayList源码过程中,偶然间发现CopyOnWriteArraySet的内部居然就是用一个CopyOnWriteArrayList实现的.

public class CopyOnWriteArraySet extends AbstractSet

implements java.io.Serializable {

private final CopyOnWriteArrayList al;

/**

  • Adds the specified element to this set if it is not already present.

  • More formally, adds the specified element {@code e} to this set if

  • the set contains no element {@code e2} such that

  • (enull ? e2null : e.equals(e2)).

  • If this set already contains the element, the call leaves the set

  • unchanged and returns {@code false}.

  • @param e element to be added to this set

  • @return {@code true} if this set did not already contain the specified

  •     element
    

*/

public boolean add(E e) {

return al.addIfAbsent(e);

}

}

而CopyOnWriteArrayList的addIfAbsent方法其实和add方法内部实现是差不多的(都是新复制数组且上锁),只不过多了层判断

/**

  • Appends the element, if not present.

  • @param e element to be added to this list, if absent

  • @return {@code true} if the element was added

*/

public boolean addIfAbsent(E e) {

Object[] snapshot = getArray();

return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :

addIfAbsent(e, snapshot);

}

/**

  • A version of addIfAbsent using the strong hint that given

  • recent snapshot does not contain e.

*/

private boolean addIfAbsent(E e, Object[] snapshot) {

final ReentrantLock lock = this.lock;

lock.lock();

try {

Object[] current = getArray();

int len = current.length;

if (snapshot != current) {

// Optimize for lost race to another addXXX operation

int common = Math.min(snapshot.length, len);

for (int i = 0; i < common; i++)

if (current[i] != snapshot[i] && eq(e, current[i]))

return false;

if (indexOf(e, current, common, len) >= 0)

return false;

}

Object[] newElements = Arrays.copyOf(current, len + 1);

newElements[len] = e;

setArray(newElements);

return true;

} finally {

lock.unlock();

}

最后

做任何事情都要用心,要非常关注细节。看起来不起眼的、繁琐的工作做透了会有意想不到的价值。
当然要想成为一个技术大牛也需要一定的思想格局,思想决定未来你要往哪个方向去走, 建议多看一些人生规划方面的书籍,多学习名人的思想格局,未来你的路会走的更远。

更多的技术点思维导图我已经做了一个整理,涵盖了当下互联网最流行99%的技术点,在这里我将这份导图分享出来,以及为金九银十准备的一整套面试体系,上到集合,下到分布式微服务

享出来,以及为金九银十准备的一整套面试体系,上到集合,下到分布式微服务**

[外链图片转存中…(img-SiveQJnV-1720120706995)]

[外链图片转存中…(img-GH7uUMxf-1720120706995)]

[外链图片转存中…(img-mc8n3zOX-1720120706996)]

[外链图片转存中…(img-wdXtEV3o-1720120706996)]

  • 30
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值