学技术学英文:java各种锁-synchronized、ReentrantLock、ReentrantReadWriteLock、StampedLock

内容导读:

1. synchronized 可以放到方法和代码块上,方法和代码块运行完了自动解锁, Lock API 有lock和unlock方法。

2.synchronized 不支持公平锁(抢占式的),  Lock API 支持公平锁(按排队顺序,先进入队列的先获取锁)

3. synchronized 如果获取不到锁会一直阻塞等待

4. Lock API 提供了多种策略 lock()会等待, tryLock()加锁成功立即返回true否则返回false ,tryLock(long time, TimeUnit unit) 可以根据参数有限等待。

5. synchronized 加锁等待期间线程不可以被interrupt,  Lock API  可以用lockInterruptibly()这个方法加锁,这个方法加锁等待期间,该线程可以被interrupt

6. ReentrantLock 可重入锁,可重入的概念是同一个线程可以的多次调用lock() 返回成功,比如递归调用中,会出现多次lock() ;  synchronized  也是可重入的。

7. ReentrantReadWriteLock 可重入读写锁;读锁也叫共享锁,可以被多个线程占用;写锁只能被某个线程独占,写锁也叫排他锁。

8. Lock API 提供了newCondition() , 一个lock可以创建多个Condition ,每个Condition自己控制wait和notify  , 和 synchronized 块里的的 wait功能一样,但synchronized至于一个(不分条件)

9. StampedLock  同时支持乐观锁和悲观锁,和锁转换的功能

  • 邮戳(Stamp):StampedLock的关键特性之一,是一个long类型的数字,用于标识锁的版本和状态。在获取锁时,会返回一个邮戳值,该值在后续的锁操作中用于验证锁的有效性。
  • 不可重入性:StampedLock不支持可重入性,即同一个线程在没有释放锁的情况下无法再次获得锁。
  • 锁转换:StampedLock支持锁之间的转换,例如可以将读锁转换为写锁,或将写锁转换为读锁。但需要注意的是,锁转换可能会失败,需要根据返回值判断是否成功。
  • 性能优势:StampedLock通过引入乐观读锁和锁转换等特性,在读多写少的场景下提供了更高的并发性能。
class Point {
   private double x, y;
   private final StampedLock sl = new StampedLock();
   void move(double deltaX, double deltaY) { // an exclusively locked method
     long stamp = sl.writeLock();
     try {
       x += deltaX;
       y += deltaY;
     } finally {
       sl.unlockWrite(stamp);
     }
   }
  //下面看看乐观读锁案例
   double distanceFromOrigin() { // A read-only method
     long stamp = sl.tryOptimisticRead(); //获得一个乐观读锁
     double currentX = x, currentY = y; //将两个字段读入本地局部变量
     if (!sl.validate(stamp)) { //检查发出乐观读锁后同时是否有其他写锁发生? 
        stamp = sl.readLock(); //如果没有,我们再次获得一个读悲观锁
        try {
          currentX = x; // 将两个字段读入本地局部变量
          currentY = y; // 将两个字段读入本地局部变量
        } finally {
           sl.unlockRead(stamp);
        }
     }
     return Math.sqrt(currentX * currentX + currentY * currentY);
   }
	//下面是悲观读锁案例
   void moveIfAtOrigin(double newX, double newY) { // upgrade
     // Could instead start with optimistic, not read mode
     long stamp = sl.readLock();
     try {
       while (x == 0.0 && y == 0.0) { //循环,检查当前状态是否符合
         long ws = sl.tryConvertToWriteLock(stamp); //将读锁转为写锁
         if (ws != 0L) { //这是确认转为写锁是否成功
           stamp = ws; //如果成功 替换票据
           x = newX; //进行状态改变
           y = newY; //进行状态改变
           break;
         }
         else { //如果不能成功转换为写锁
           sl.unlockRead(stamp); //我们显式释放读锁
           stamp = sl.writeLock(); //显式直接进行写锁 然后再通过循环再试
         }
       }
     } finally {
       sl.unlock(stamp); //释放读锁或写锁
     }
   }
 }

1. Overview

Simply put, a lock is a more flexible and sophisticated thread synchronization mechanism than the standard synchronized block.

The Lock interface has been around since Java 1.5. It’s defined inside the java.util.concurrent.lock package, and it provides extensive operations for locking.

In this tutorial, we’ll explore different implementations of the Lock interface and their applications.

2. Differences Between Lock and Synchronized Block

There are a few differences between the use of synchronized block and using Lock APIs:

  • synchronized block is fully contained within a method. We can have Lock APIs lock() and unlock() operation in separate methods.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值