Java刷题错题笔记-day05-集合(CopyOnWriterArrayList、HashMap)

1.CopyOnWriterArrayList是强一致性列表吗?

不是

CopyOnWriteArrayList 不提供强一致性主要是因为它的修改操作是在一个新的拷贝上进行的,而不是直接在原始数据结构上。这种设计决策带来了一些影响:

  1. 读取操作不阻塞: CopyOnWriteArrayList 的读取操作是在原始数组上进行的,无锁,而写入在原数组的拷贝上进行。因此,写入操作期间,读取操作不会被阻塞,允许并发读取。但这也意味着在写入操作完成之前,读取操作可能会看到旧的数据。
  2. 写入操作的延迟: 当有写入操作发生时,CopyOnWriteArrayList 会创建一个新的数组,并在上面执行修改。在这个过程中,其他线程可能仍然在引用旧的数组。因此,在写入操作完成之前,其他线程可能无法感知到最新的修改。

下面是简化的 CopyOnWriteArrayList 的部分关键代码,以便更好地理解:

public class CopyOnWriteArrayList<E> {
    
   private transient volatile Object[] array;

   // ...
	  /**
		*写入操作
		/
   public boolean add(E element) {
       synchronized (this) {
           Object[] currentArray = array;
           //1.拷贝原数组
           Object[] newArray = Arrays.copyOf(currentArray, currentArray.length + 1);
           //2.在新副本上执行添加操作
           newArray[currentArray.length] = element;
           //3.将原数组引用指向新副本
           array = newArray;
           return true;
       }
   }

   // ...

   public E get(int index) {
       return (E) array[index];
   }

   // ...
}

add 方法中,修改是在一个新的数组上进行的。而 get 方法只是直接访问当前数组,没有加锁,因此可能在写入操作进行时看到旧的数组。这就是导致不强一致性的主要原因之一。

2.HashMap允许key为null吗?

允许

key为null时,key的hash值恒为0,元素将被存储在数组的第一个位置

public V put(K key, V value) {
    
   return putVal(hash(key), key, value, false, true);
}


static final int hash(Object key) {
    
   int h;
   //key为null,hash恒为0
   return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

final V putVal(int hash, K key, V value,<
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摸魚散人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值