CopyOnWirte思想
CopyOnWrite指在"写"的时候不直接"写"源数据,而是把数据拷贝一份进行修改,然后再通过悲观锁或者乐观锁的方式写回。
主要就是为了让在“读”的时候不加锁。因为一般来说读写是互斥的,写的过程中我们如果读可能读到脏数据,但是如果我们拷贝一份去修改再写回,那么只有写回的这一步是线程不安全的,因为修改的时候是操作的副本。
那么我们要解决两个问题:
- 写回的操作要线程安全
- 写回的操作要happens-before于读的操作
解决写回操作的线程安全
public boolean add(E e) {
final ReentrantLock lock = this.lock;
//直接用悲观锁锁住,同时只会有一个写入
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
一般来说保证线程安全的加锁有悲观锁和乐观锁两种,这里用的悲观锁
解决写回的操作要happens-before于读的操作
/** The array, accessed only via getArray/setArray. */
private transient volatile Object[] array;
//volatile解决
//这样我们可以保证每次写回后都能被马上读到
至于读的操作,直接读就好了