AQS

AQS是阻塞式锁和相关同步器框架。

特点:

  1. 使用state来表示资源状态,子类维护状态,通过状态控制是否获取到锁
    1. getState - 获取 state 状态
    2. setState - 设置 state 状态
    3. compareAndSetState - cas 机制设置 state 状态
  2. state分独占模式和共享模式,独占模式只有一个线程可以访问资源
  3. 提供了基于FIFO的等待队列类似EntryList
  4. 提供了条件变量来实现等待通知,类似WaitSet

子类主要实现这样一些方法(默认抛出 UnsupportedOperationException)
tryAcquire
tryRelease
tryAcquireShared
tryReleaseShared
isHeldExclusively

CLH队列

AQS内部通过CLH队列来维护线程状态,是一个FIFO双向队列,入队时通过CAS+volatile的方式添加元素。

                node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
CLH队列添加元素示意图

出队(解锁):将head指向node,p的next置位null。解锁不需要CAS。因为当前线程本身还持有锁呢,不会存在竞争。

                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
出队示意图

state设计

state 使用 volatile 配合 cas 保证其修改时的原子性
使用32位int表示state状态

阻塞恢复设计

使用park&unpark来实现阻塞恢复

使用AQS自定义不可重入锁

package com.demo.lock;

import javafx.beans.binding.When;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class MyLock implements Lock {
    MySync mySync = new MySync();

    @Override//失败进入阻塞队列
    public void lock() {
        mySync.acquire(1);
    }

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

    @Override//只尝试一次,失败放弃
    public boolean tryLock() {
        return mySync.tryAcquire(1);
    }

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

    @Override
    public void unlock() {
        mySync.release(1);
    }

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

    class MySync extends AbstractQueuedSynchronizer {
        @Override
        protected boolean tryAcquire(int arg) {
            if (arg == 1) {
                if (compareAndSetState(0, 1)) {
                    setExclusiveOwnerThread(Thread.currentThread());
                    return true;
                }
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            if (arg == 1) {
                if (getState() == 0) {
                    throw new IllegalMonitorStateException();
                }
                compareAndSetState(1, 0);
                setExclusiveOwnerThread(null);
                return true;
            }
            return false;
        }

        @Override
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }

        protected Condition newCondition() {
            return new ConditionObject();
        }
    }
}

你可能感兴趣的:(AQS)