相对而言,乐观锁则是基于积极乐观的假设:以为大部分情况下多个线程同时访问同一资源并不会发生冲突。因此,乐观锁答应线程无须获取锁就可以实行业务逻辑,仅在更新数据时接纳CAS(Compare And Swap)原子操纵检查并更新数据。假如发现数据已被其它线程改变,则放弃本次更新,通常会重新读取数据并再次尝试。
以Java中的AtomicInteger为例,它利用CAS机制实现了乐观锁的特性:
public class OptimisticLockExample {<br> private final AtomicInteger counter = new AtomicInteger(10);<br><br> public void incrementCounter() {<br> while (true) { // 自旋<br> int currentValue = counter.get();<br> int newValue = currentValue + 1;<br> if (counter.compareAndSet(currentValue, newValue)) { // 使用CAS原子操作<br> break; // 更新成功,退出循环<br> }<br> }<br> }<br>}<br><br>// AtomicInteger 的 compareAndSet 方法源码简化示意<br>public final boolean compareAndSet(int expect, int update) {<br> return unsafe.compareAndSwapInt(this, valueOffset, expect, update);<br>}<br><br>
public native boolean compareAndSwapObject(Object o, long offset, Object expected, Object x);<br>public native boolean compareAndSwapInt(Object o, long offset, int expected, int x);<br>public native boolean compareAndSwapLong(Object o, long offset, long expected, long x);<br><br>
public final int getAndAddInt(Object o, long offset, int delta) {<br> int v;<br> do {<br> v = getIntVolatile(o, offset); // 获取当前值<br> } while (!weakCompareAndSetInt(o, offset, v, v + delta)); // 使用CAS尝试更新<br> return v; // 返回更新前的值<br>}<br><br>
private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value");<br><br>
复制代码
然后,深入到Unsafe类的getAndAddInt()方法实现:
public final int getAndAddInt(Object o, long offset, int delta) {<br> int v;<br> do {<br> v = getIntVolatile(o, offset); // 获取volatile类型的旧值<br> } while (!weakCompareAndSetInt(o, offset, v, v + delta)); // 使用CAS更新新值<br> return v; // 返回更新前的值<br>}<br><br>
class Data {<br> int a;<br> int b;<br>}<br>AtomicReference<Data> atomicData = new AtomicReference<>(new Data(1, 2));<br>// 更新a和b字段的原子操作<br>Data newData = new Data(3, 4);<br>atomicData.compareAndSet(currentData, newData);<br><br>