解析乐观锁与悲观锁

简单理解:

悲观锁:假设每次都会发生并发冲突,所以每次都上锁,适用于写多读少的情况,对于高并发场景不友好,高并发的场景下频繁地对代码加锁会影响其并发性能,可能造成拥塞;

乐观锁:假设不会发生冲突,只有当产生冲突的时候才进行回溯,适合读多写少的情况;乐观锁控制冲突的原理是依靠一个数据版本,每次在开始使用的时候给数据一个版本号,而提交的时候再去看这个版本号是否发生变化,以确定是否产生冲突。因此,乐观锁不适用于长事务,因为长事务可能会造成提交的时候反复回滚;

以银行的存取存款和读取为例,悲观锁和乐观锁在java中的实现:

悲观锁:

public class BankAccountPessimistic {
    private int balance;

    public BankAccountPessimistic(int initialBalance) {
        this.balance = initialBalance;
    }

    // 悲观锁:使用synchronized实现
    public synchronized void deposit(int amount) {
        balance += amount;
        System.out.println(Thread.currentThread().getName() + " deposited " + amount + ", balance: " + balance);
    }

    public synchronized void withdraw(int amount) {
        if (balance >= amount) {
            balance -= amount;
            System.out.println(Thread.currentThread().getName() + " withdrew " + amount + ", balance: " + balance);
        } else {
            System.out.println(Thread.currentThread().getName() + " failed to withdraw " + amount + ", insufficient balance.");
        }
    }

    public synchronized int getBalance() {
        return balance;
    }
    
    public static void main(String[] args) {
        BankAccountPessimistic account = new BankAccountPessimistic(100);

        Thread t1 = new Thread(() -> {
            account.deposit(50);
            account.withdraw(30);
        }, "Thread 1");

        Thread t2 = new Thread(() -> {
            account.withdraw(70);
            account.deposit(20);
        }, "Thread 2");

        t1.start();
        t2.start();
    }
}

乐观锁:

import java.util.concurrent.atomic.AtomicInteger;

public class BankAccountOptimistic {
    private AtomicInteger balance;
    private AtomicInteger version;

    public BankAccountOptimistic(int initialBalance) {
        this.balance = new AtomicInteger(initialBalance);
        this.version = new AtomicInteger(0);
    }

    // 乐观锁:使用AtomicInteger的compareAndSet实现
    public void deposit(int amount) {
        int currentVersion;
        int newBalance;
        do {
            currentVersion = version.get();
            newBalance = balance.get() + amount;
        } while (!version.compareAndSet(currentVersion, currentVersion + 1));
        
        balance.set(newBalance);
        System.out.println(Thread.currentThread().getName() + " deposited " + amount + ", balance: " + balance.get());
    }

    public void withdraw(int amount) {
        int currentVersion;
        int newBalance;
        do {
            currentVersion = version.get();
            if (balance.get() < amount) {
                System.out.println(Thread.currentThread().getName() + " failed to withdraw " + amount + ", insufficient balance.");
                return;
            }
            newBalance = balance.get() - amount;
        } while (!version.compareAndSet(currentVersion, currentVersion + 1));

        balance.set(newBalance);
        System.out.println(Thread.currentThread().getName() + " withdrew " + amount + ", balance: " + balance.get());
    }

    public int getBalance() {
        return balance.get();
    }

    public static void main(String[] args) {
        BankAccountOptimistic account = new BankAccountOptimistic(100);

        Thread t1 = new Thread(() -> {
            account.deposit(50);
            account.withdraw(30);
        }, "Thread 1");

        Thread t2 = new Thread(() -> {
            account.withdraw(70);
            account.deposit(20);
        }, "Thread 2");

        t1.start();
        t2.start();
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值