在Java中,悲观锁和乐观锁是用于解决并发访问共享资源时可能发生的数据不一致问题的两种不同的锁机制。
悲观锁的机制是在访问共享资源之前,先锁定资源,保证其他线程无法同时访问,只有当前线程完成操作后才释放锁。Java中常用的悲观锁机制是使用synchronized关键字或ReentrantLock类来实现。
示例代码:
public class PessimisticLockExample {
private int sharedData = 0;
private final Object lock = new Object();
public void increment() {
synchronized (lock) {
sharedData++;
}
}
public int getSharedData() {
synchronized (lock) {
return sharedData;
}
}
}
在上述示例中,使用了synchronized来保证在执行increment()和getSharedData()方法时只有一个线程能够访问sharedData变量。
乐观锁的机制是假设在操作共享资源时不会发生冲突,因此不会使用显式的锁来保护资源。相反,每个线程在读取和修改资源之前会先对资源进行一次快照,然后在更新时检查快照是否发生了变化。如果快照发生了变化,意味着其他线程已经修改了资源,当前线程需要重新读取资源并重新执行操作。Java中常用的乐观锁机制是使用Atomic类或版本号机制来实现。
示例代码:
public class OptimisticLockExample {
private AtomicInteger sharedData = new AtomicInteger(0);
public void increment() {
int oldValue;
int newValue;
do {
oldValue = sharedData.get();
newValue = oldValue + 1;
} while (!sharedData.compareAndSet(oldValue, newValue));
}
public int getSharedData() {
return sharedData.get();
}
}
在上述示例中,使用了AtomicInteger类的compareAndSet()方法来实现乐观锁机制,保证只有当sharedData的值没有发生变化时才会进行更新操作。
需要注意的是,悲观锁和乐观锁各有其适用的场景和优缺点。悲观锁在并发量较大或预期冲突较多的情况下效果较好,但会带来较大的开销。乐观锁在并发量较小或预期冲突较少的情况下效果较好,但需要注意处理冲突的情况。因此,在使用锁机制时需要根据具体情况选择合适的锁机制。