您好,欢迎来到爱够旅游网。
搜索
您的当前位置:首页悲观锁/乐观锁

悲观锁/乐观锁

来源:爱够旅游网

一、悲观锁

   public class SynchronizedExample {
       private int count = 0;
       public synchronized void increment() {
           count++;
       }
       public int getCount() {
           return count;
       }
   }
  • 在上述代码中,increment方法被synchronized修饰。当一个线程进入increment方法时,它会获取this对象(当前实例)的锁。其他线程如果也想调用increment方法,就必须等待这个线程释放锁。
   import java.util.concurrent.locks.ReentrantLock;
   public class ReentrantLockExample {
       private int count = 0;
       private ReentrantLock lock = new ReentrantLock();
       public void increment() {
           lock.lock();
           try {
               count++;
           } finally {
               lock.unlock();
           }
       }
       public int getCount() {
           return count;
       }
   }

  • 这里使用ReentrantLock来实现悲观锁。在increment方法中,首先通过lock.lock()获取锁,然后在finally块中通过lock.unlock()释放锁,确保在任何情况下锁都能被正确释放。 
  • 适用场景
    • 适用于写操作比较频繁的场景。因为写操作可能会导致数据的不一致性,使用悲观锁可以有效避免这种情况。例如,在一个银行账户转账系统中,当一个线程正在进行转账操作(修改账户余额)时,其他线程必须等待,以确保账户余额的准确性。

二、乐观锁

  1. 定义
    • 乐观锁假设数据一般情况下不会产生冲突,所以在数据更新的时候,才会去检查数据是否被其他线程修改过。如果没有被修改,就直接更新;如果被修改了,就根据不同的策略来处理,比如重试或者抛出异常。
    • 这就好比一个人在使用公共资源时,先不考虑是否会和别人冲突,等要更新资源的时候,才检查一下资源是否被别人修改过。
  2. 实现方式
    • 常见的实现方式是使用版本号(version)或者时间戳(timestamp)。

   class OptimisticLockExample {
       private int value;
       private int version;
       public void updateValue(int newValue) {
           // 先检查版本号
           if (version == getVersionFromDB()) {
               // 如果版本号一致,更新值和版本号
               value = newValue;
               version++;
               updateDBValueAndVersion(value, version);
           } else {
               // 版本号不一致,可能有其他线程修改了数据,可以选择重试或者抛出异常
               throw new ConcurrentModificationException("Data has been modified by other threads");
           }
       }
       private int getVersionFromDB() {
           // 从数据库中获取版本号的模拟方法
           return version;
       }
       private void updateDBValueAndVersion(int newValue, int newVersion) {
           // 更新数据库中的值和版本号的模拟方法
       }
   }
  • 在这个例子中,每次更新value之前,都会检查version是否和数据库中的版本号一致。如果一致,说明数据没有被其他线程修改,可以进行更新操作,并且更新后版本号加 1;如果不一致,说明数据已经被其他线程修改,根据业务需求可以选择抛出异常或者重试操作。
  • 适用场景
    • 适用于读操作比较频繁的场景。因为读操作不会对数据进行修改,发生冲突的概率相对较低。使用乐观锁可以提高系统的并发性能。例如,在一个新闻网站的文章浏览系统中,多个用户同时浏览文章(读操作),只有在编辑修改文章(写操作)时才需要检查是否有冲突,这种情况下使用乐观锁可以让更多的用户同时进行浏览操作。

  • Timestamp类在精度上更准确(精确到毫秒),并且提供了一些与数据库交互更方便的方法。
  • Date类主要用于表示日期和时间,但在处理数据库相关操作时可能需要额外的转换。
  • Calendar类主要用于日期时间的计算和操作,如日期的加减等。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- igbc.cn 版权所有 湘ICP备2023023988号-5

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务