关于AQS详解

这段时间自己学了下并发编程,然后发现提供的并发工具全部都和AQS有关。无论是Lock还是信号量,计数器等,都逃不过与AQS的联系。写这篇博客的初衷其实是自己想写一些并发工具类的文章,包括countdownlatch或者信号量之类的,但是它们底层都涉及到了AQS,所以先写这个AQS,一来是为了让自己更深刻的理解,二来是让大家阅读的时候有个参考。话不多说,开始今天的AQS

AQS(AbstractQueuedSynchronizer)抽象的队列同步器。简单来说AQS就是一个用来构建锁或者其他同步组件的一个框架,就是一个工具类。(它本身是个抽象类)

AQS的主要使用方式就是继承,通过继承AQS来重写一些满足自己逻辑的方法——这就是模板设计模式

在AQS中设置了一个int类型的state,用它来表示是否获得了锁之类的情况。

下面先来看看对应的一些方法

下面是能够重写的方法(如果你需要自己设计一些锁或者同步工具类,那么一定要选择自己适合的方法去写自己对应的业务规则):

我们现在自己手写一个简单的独占锁,且不可重入

/**
 * 独占锁,不可重入
 */
public class SelfLock implements Lock {

    private static class Syn extends AbstractQueuedSynchronizer{

        /**
         *  返回一个Condition,每个condition都包含了一个condition队列
         */
        Condition newCondition() {
            return new ConditionObject();
        }

        @Override
        protected boolean tryAcquire(int arg) {
            if(compareAndSetState(0,1)){
                setExclusiveOwnerThread(Thread.currentThread());//设置当前线程为占有锁的线程
                System.out.println("当前线程 "+getExclusiveOwnerThread().getName()+" 获取锁");
                return true;
            }
            return false;
        }      

        
       @Override
       protected boolean tryRelease(int arg){
       //判断是否同一个操作 
       if(getExclusiveOwnerThread().equals(Thread.currentThread())){
          setExclusiveOwnerThread(null);
          setState(0);
          System.out.println("当前线程 "+Thread.currentThread().getName()+" 释放锁");
          return ture; 
        //不需要使用cas操作,因为获得了锁的才能释放锁
        //compareAndSetState(1,0);
        }
        return false;
      }


        /**
         * 判断是否占用
         * @return
         */
        @Override
        protected boolean isHeldExclusively() {
            return (getState()==1);
        }
    }


    private Syn syn = new Syn();

    @Override
    public void lock() {
        syn.acquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        syn.acquireInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        return syn.tryAcquire(1);
    }

    @Override
    public boolean tryLock(long time, TimeUnit timeUnit) throws InterruptedException {
        return syn.tryAcquireNanos(1,timeUnit.toNanos(time));
    }

    @Override
    public void unlock() {
        syn.tryRelease(1);
    }

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

因为是非公平锁,所以我们继承AQS重写了三个方法,tryAcquire(尝试获取锁),tryRelease(尝试释放锁)isHeldExclusively(是否占有锁);<

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值