4. AQS

1. AQS

1.1 CLH 队列锁

在这里插入图片描述

1.2 AbstractQueuedSynchronizer

队列同步器 AbstractQueuedSynchronizer(AQS),是用来构建锁或者其他同步组件的基础框架,它使用了一个 int 成员变量 state 表示同步状态(加锁状态),通过内置的 FIFO 队列来完成资源获取线程的排队工作。

AQS 是基于 CLH 的变种实现。

使用 AQS 实现自己的锁,使用的是模板模式,需要自己实现模板方法:
1.
2.

/**
 * 自己实现独占锁,可重入
 */
public class ReenterSelfLock implements Lock {
    // 静态内部类,自定义同步器
    private static class Sync extends AbstractQueuedSynchronizer {

        // 是否处于占用状态
        protected boolean isHeldExclusively() {
            return getState() > 0;
        }

        // 当状态为0的时候获取锁
        public boolean tryAcquire(int acquires) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            } else if (getExclusiveOwnerThread() == Thread.currentThread()) {
                setState(getState() + 1);
                return true;
            }
            return false;
        }

        // 释放锁,将状态设置为0
        protected boolean tryRelease(int releases) {
            if (getExclusiveOwnerThread() != Thread.currentThread()) {
                throw new IllegalMonitorStateException();
            }
            if (getState() == 0) {
                throw new IllegalMonitorStateException();
            }

            setState(getState() - 1);
            if (getState() == 0) {
                setExclusiveOwnerThread(null);
            }
            return true;
        }

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

    private final Sync sync = new Sync();

    public void lock() {
        sync.acquire(1);
    }

    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    public void unlock() {
        sync.release(1);
    }

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

    public boolean isLocked() {
        return sync.isHeldExclusively();
    }

    public boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }

    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }
}

2. 显式锁

2.1 Lock 接口

在这里插入图片描述
标准使用范式是:解锁代码要放在 finally 中,确保业务代码出现异常时,可以解锁。在这里插入图片描述

2. 显式锁

  1. 可重入锁:加锁线程可再次对同一资源加锁。
    ReentrantLock 是可重入锁,synchronized 也是可重入锁。
  2. 公平锁、非公平锁:先抢锁线程先拿到锁是公平锁,否则为非公平锁。
    非公平锁效率更高。

2.1 ReentrantLock

2.2 读写锁:ReadWriteLock、ReentrantReadWriteLock

相对独占锁而言。
读写锁的排斥性:读读不排斥、读写排斥、写写排斥。

public class UseRwLock implements GoodsService {

    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock getLock = lock.readLock();//读锁
    private final Lock setLock = lock.writeLock();//写锁

    @Override
    public GoodsInfo getNum() {
        getLock.lock();
        try {
            SleepTools.ms(5);
            return null;
        } finally {
            getLock.unlock();
        }
    }

    @Override
    public void setNum(int number) {
        setLock.lock();
        try {
            SleepTools.ms(5);
        } finally {
            setLock.unlock();
        }
    }
}

2.3 Condition

在这里插入图片描述

    private Lock kmLock = new ReentrantLock();
    private Condition kmCond = kmLock.newCondition();
    private Lock siteLock = new ReentrantLock();
    private Condition siteCond = siteLock.newCondition();

2.4 LockSupport

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值