jdk8 和jdk14 的CopyOnWrite里面用的锁机制已经发生了改变
以CopyOnWriteArrayList为例 查看其源码 以add方法为例:
// JDK14
public boolean add(E e) {
synchronized (lock) {
Object[] es = getArray();
int len = es.length;
es = Arrays.copyOf(es, len + 1);
es[len] = e;
setArray(es);
return true;
}
}
// jdk8
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();
}
}
可以发现jdk8 用的是reentrantLock可重入锁 而jdk14用的是synchronized块 而且代码更加简练
一般来说reentrantLocklock机制会更好 但是jdk14是升级版 为什么会从reentrantLocklock变成synchronized?
其实当我们在使用锁时候,synchronized应该是我们的第一选择,除非是遇到瓶颈,synchronized无法解决,应该再使用lock类。
lock的实现类是JVM无法控制的,很容易发生死锁,因此必须有finally中的解锁。而JVM可以在synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生。
synchronized是java的一个关键字,其实有很多先天的优点。