Java中的乐观锁和悲观锁都是用于并发控制的机制,用于解决多个线程同时访问共享资源时的数据安全问题。
- 悲观锁:指的是在访问共享资源之前,先对资源进行加锁,确保其他线程无法同时访问资源。悲观锁的代表是synchronized关键字和ReentrantLock类。
- 乐观锁:指的是不对共享资源进行加锁,而是通过版本号等方式判断资源是否被其他线程修改。乐观锁的代表是CAS算法。
CAS(Compare and Swap)是一种无锁算法,用于解决并发访问共享资源的问题,它是一种乐观锁的实现方式。除了原子类之外,还有一些其他的用法,如下所示:
- 使用Unsafe类提供的CAS方法进行操作。
- 使用AtomicReferenceFieldUpdater、AtomicIntegerFieldUpdater等工具类,可以实现对普通对象中字段的原子更新。
- 使用sun.misc.Contended注解,可以防止伪共享问题。
使用CAS算法的基本步骤如下:
- 读取共享资源的当前值和版本号。
- 对共享资源进行修改,计算新的值和版本号。
- 使用CAS操作尝试将共享资源的值和版本号更新为新值和新版本号。
- 如果CAS操作成功,则更新成功;否则,重复上述步骤。
示例代码如下:
import java.util.concurrent.atomic.AtomicInteger;
public class CASExample {
private static AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args) {
new Thread(() -> {
int oldValue = count.get();
int newValue = oldValue + 1;
while (!count.compareAndSet(oldValue, newValue)) {
oldValue = count.get();
newValue = oldValue + 1;
}
System.out.println(Thread.currentThread().getName() + " count is " + count.get());
}).start();
}
}
以上代码中,使用AtomicInteger类来维护共享资源的值,使用compareAndSet方法进行CAS操作。在更新共享资源时,如果CAS操作失败,则重复尝试直到操作成功为止。