JUC并发编程:AQS原理自定义锁

概述

AQS全称是 AbstractQueuedSynchronizer,是阻塞式锁和相关的同步器工具的框架
特点:

  • 用 state 属性来表示资源的状态(分独占模式和共享模式),子类需要定义如何维护这个状态,控制如何获取
    锁和释放锁
    getState - 获取 state 状态
    setState - 设置 state 状态
    compareAndSetState - cas 机制设置 state 状态
    独占模式是只有一个线程能够访问资源,而共享模式可以允许多个线程访问资源
  • 提供了基于 FIFO 的等待队列,类似于 Monitor 的 EntryList
  • 条件变量来实现等待、唤醒机制,支持多个条件变量,类似于 Monitor 的 WaitSet
    子类主要实现这样一些方法(默认抛出 UnsupportedOperationException)
    tryAcquire
    tryRelease
    tryAcquireShared
    tryReleaseShared
    isHeldExclusively
    获取锁的姿势:
// 如果获取锁失败
if (!tryAcquire(arg)) {
// 入队, 可以选择阻塞当前线程 park unpark
}

释放锁的姿势:

// 如果释放锁成功
if (tryRelease(arg)) {
// 让阻塞线程恢复运行
}

实现不可重入锁

自定义队列同步器

    //自定义队列同步器的实现
   final class MyAQS extends AbstractQueuedSynchronizer{
       //尝试获取锁只有一次
       @Override
       protected boolean tryAcquire(int arg) {
           if (arg == 1){
               if(compareAndSetState(0,1)){
                   setExclusiveOwnerThread(Thread.currentThread());
                   setState(1);
                   return true;
               }
           }
           return false;
       }

       @Override
       protected boolean tryRelease(int arg) {
           //这里别写错了是1不是0 我写错了锁没释放...
           if (arg == 1){
               setExclusiveOwnerThread(null);
               setState(0);
               return true;
           }
            return false;
       }
       //当前线程是否持有锁
       @Override
       protected boolean isHeldExclusively() {
           return getState() == 1;
       }
       protected Condition newCondition(){
           return new ConditionObject();
       }
   }

自定义锁(不可重入锁)

public class MyLock implements Lock {
   MyAQS sync = new MyAQS();
   //如果获取锁失败,会将其加入到同步队列中
   //而tryAcquire是获取一次失败拉倒 acquired内部是tryAcquire 需要我们自己实现它
   @Override
   public void lock() {
       //直接调用父类的模板方法即可
        sync.acquire(1);
   }

   @Override
   public void lockInterruptibly() throws InterruptedException {
       //直接调用父类的模板方法即可
        sync.acquireInterruptibly(1);
   }

   @Override
   public boolean tryLock() {
       //调用我们重写的方法
       return sync.tryAcquire(1);
   }

   @Override
   public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
       //调用父类的模板方法
       return sync.tryAcquireNanos(1,unit.toNanos(time));
   }

   //解锁(解锁解一次就行了)
   @Override
   public void unlock() {
      sync.release(1);
   }

   @Override
   public Condition newCondition() {
       return sync.newCondition();
   }
}

日志依赖

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jul-to-slf4j</artifactId>
            <version>2.0.13</version>
        </dependency>
    </dependencies>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值