AQS

什么是AQS

AQS,指的是AbstractQueuedSynchronizer,它提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架,ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier等并发类均是基于AQS来实现的。

AQS使用方式和其中的设计模式

继承,模板方法设计模式

独占式锁代表:ReentrantLock

共享式锁代表:ReadLock

模板方法:

独占式获取

accquire

acquireInterruptibly

tryAcquireNanos

共享式获取

acquireShared

acquireSharedInterruptibly

tryAcquireSharedNanos

独占式释放锁

release

共享式释放锁

releaseShared

需要子类覆盖的流程方法

独占式获取  tryAcquire

独占式释放  tryRelease

共享式获取 tryAcquireShared

共享式释放  tryReleaseShared

这个同步器是否处于独占模式  isHeldExclusively

同步状态state:

getState:获取当前的同步状态

setState:设置当前同步状态

compareAndSetState 使用CAS设置状态,保证状态设置的原子性

 LockSupport

主要用于将一个线程设置为阻塞状态,或者唤醒线程

 

AQS_第1张图片

pack 阻塞

unpack 唤醒                                                                                                                                                                               

独占式流程

 AQS_第2张图片

 自实现ReentrantLock

public class MyReentrantLock implements Lock {
    //state 表示获取到锁 state=1 获取到了锁,state=0,表示这个锁当前没有线程拿到
    private static class Sync extends AbstractQueuedSynchronizer {
        //是否处于独占模式
        @Override
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }

        //尝试获取锁
        @Override
        protected boolean tryAcquire(int arg) {
            if (compareAndSetState(0, 1)) {
                //设置当前线程为锁拥有者
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        //尝试释放该锁
        @Override
        protected boolean tryRelease(int arg) {
            if(getState() == 0){//当前状态为未持有锁状态,则直接抛错
                throw new UnsupportedOperationException();
            }
            //设置锁的持有者为null
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

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

    static Sync sync = new Sync();

    @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();
    }
}
public class AQSTest {
    static Lock lock = new MyReentrantLock();

    static class MyThread extends Thread {
        @Override
        public void run() {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + " start to do work");
                Thread.sleep(5);
                System.out.println(Thread.currentThread().getName() + " work done");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new MyThread().start();
        }
    }
}

运行结果:

Thread-0 start to do work
Thread-0 work done
Thread-4 start to do work
Thread-4 work done
Thread-2 start to do work
Thread-2 work done
Thread-1 start to do work
Thread-1 work done
Thread-3 start to do work
Thread-3 work done

根据结果显示,独占锁生效。

自实现Semaphore

原理:设置共享锁,设定同时最多可以有几个线程获取该锁

public class MySemaphore implements Lock {
    Sync sync = new Sync(3);

    static class Sync extends AbstractQueuedSynchronizer {
        //设置AbstractQueuedSynchronizer的state的个数,根据对state的数量的判断,来实现同时最多几个线程获取锁
        Sync(int count) {
            if (count < 0) {
                throw new IllegalArgumentException("count must large than zero.");
            }
            setState(count);
        }

        //共享锁子类需要重写的方法
        @Override
        protected int tryAcquireShared(int reduceCount) {
            for (;;) {
                int current = getState();
                int newCount = current - reduceCount;
                if (newCount < 0 || compareAndSetState(current, newCount)) {
                    return newCount;
                }
            }
        }

        //共享锁子类需要重写的方法
        @Override
        protected boolean tryReleaseShared(int returnCount) {
            for (;;) {
                int current = getState();
                int newCount = current + returnCount;
                if (compareAndSetState(current, newCount)) {
                    return true;
                }
            }
        }

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

    }

    @Override
    public void lock() {
        sync.acquireShared(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        return sync.tryAcquireShared(1) >= 0;
    }

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

    @Override
    public void unlock() {
        sync.releaseShared(1);
    }

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

public class MySemaphoreTest {
    static MySemaphore semaphore = new MySemaphore();

    static class MyThread extends Thread {
        @Override
        public void run() {
            semaphore.lock();
            try {
                System.out.println(Thread.currentThread().getName() + ":" + System.currentTimeMillis());
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                semaphore.unlock();
            }
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new MyThread().start();
        }
    }
}

运行结果:

Thread-0:1590145302725
Thread-2:1590145302725
Thread-1:1590145302725
Thread-4:1590145304725
Thread-5:1590145304725
Thread-6:1590145304726
Thread-3:1590145306725
Thread-8:1590145306725
Thread-9:1590145306726
Thread-7:1590145308725

 

你可能感兴趣的:(并发编程,多线程,java)