Java 乐观锁

Java 乐观锁

核心概念

悲观锁

  • 假设最坏情况,每次访问共享资源时都会有其他线程来修改数据。
  • 访问之前会先加锁,确保同一时刻只有一个线程操作数据。
  • 代表实现:synchronized、Lock、数据库中的行锁、表锁。

乐观锁

  • 假设大多数情况没有冲突,允许多个线程同时访问数据。
  • 访问共享资源时不会加锁,而是判断数据是否被其他线程修改过。
  • 若数据被修改,则重新获取数据,直到数据未被修改再执行操作。
  • 实现方式:CAS(Compare And Swap)、版本号机制。

Java 中乐观锁的代表类

  • AtomicInteger
  • AtomicLong
  • AtomicReference
  • AtomicStampedReference
  • AtomicMarkableReference
  • 等等

代码实现示例

package com.optimisticlock;

import sun.misc.Unsafe;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 悲观锁:假设最坏情况,每次访问共享资源时都会有其他线程来修改数据,因此在访问之前会先加锁,确保同一时刻只有一个线程操作数据
 *      synchronized
 *      Lock
 *      数据库中的行锁、表锁
 * 乐观锁:假设大多数情况没有冲突,允许多个线程同时访问数据,每次访问共享资源时,不会加锁,而是判断数据是否被其他线程修改过,如果被修改过,则重新获取数据,直到没有被修改过
 *      CAS(Compare And Swap)
 *      版本号机制
 *  java中乐观锁的代表:
 *      AtomicInteger
 *      AtomicLong
 *      AtomicReference
 *      AtomicStampedReference
 *      AtomicMarkableReference
 *      等等
 * @author Jing61
 */
public class OptimisticLock {
    // volatile修饰的变量,会保证可见性,不会被JVM指令重排序
    private volatile int value;
    private static final Unsafe U = Unsafe.getUnsafe();

    // 内存中的偏移量
    private static final long VALUE;

    static {
        try {
            VALUE = U.objectFieldOffset(OptimisticLock.class.getDeclaredField("value"));
        } catch (NoSuchFieldException e) {
            throw new Error(e);
        }
    }

    public static void main(String[] args) {
        // 1.利用 CAS
        OptimisticLock optimisticLock = new OptimisticLock();
        // 获取当前值
        int expected = optimisticLock.value;
        while (!U.compareAndSwapInt(optimisticLock, VALUE, expected, expected + 1)) {
            expected = optimisticLock.value;
        }
        // 2. AtomicInteger
        AtomicInteger atomicInteger = new AtomicInteger();
        // getAndIncrement()方法是使得当前值增加1,如果当前值被修改过,则会重新获取当前值,直到没有被修改过
        System.out.println(atomicInteger.getAndIncrement());
    }

}

补充说明

  • volatile 关键字作用:保证变量的可见性,禁止JVM对指令进行重排序,确保多线程环境下变量值的更新能被及时感知。
  • Unsafe 类:提供底层CAS操作支持,通过objectFieldOffset获取变量在对象中的内存偏移量,用于直接操作内存数据。
  • Atomic 系列类优势:无需手动编写CAS循环逻辑,底层已封装安全高效的乐观锁实现,简化多线程并发编程。
posted @ 2025-11-14 16:30  Jing61  阅读(6)  评论(0)    收藏  举报