如何设计旅游网站的域名,天津网站制作首页在线咨询,wordpresS追踪访问轨迹,wordpress自动保存图片AQS底层原理AQS(AbstractQueuedSynchronizer)是一个抽象同步队列#xff0c;JUC(java.util.concurrent)中很多同步锁都是基于AQS实现的。AQS的基本原理就是当一个线程请求共享资源的时候会判断是否能够成功操作这个共享资源#xff0c;如果可以就会把这个共享资源设置为锁定状…AQS底层原理AQS(AbstractQueuedSynchronizer)是一个抽象同步队列JUC(java.util.concurrent)中很多同步锁都是基于AQS实现的。AQS的基本原理就是当一个线程请求共享资源的时候会判断是否能够成功操作这个共享资源如果可以就会把这个共享资源设置为锁定状态如果当前共享资源已经被锁定了那就把这个请求的线程阻塞住也就是放到队列中等待。state变量AQS中有一个被volatile声明的变量用来表示同步状态提供了getState()、setState()和compareAndSetState()方法来修改state状态的值// 返回同步状态的当前值protected final int getState() {return state;}// 设置同步状态的值protected final void setState(int newState) {state newState;}// CAS操作修改state的值protected final boolean compareAndSetState(int expect, int update) {return unsafe.compareAndSwapInt(this, stateOffset, expect, update);}对共享资源的操作方式上面说了AQS是JUC中很多同步锁的底层实现锁也分很多种有像ReentrantLock这样的独占锁也有ReentrantReadWriteLock这样的共享锁所以AQS中也必然是包含这两种操作方式的逻辑独占式获取资源的时候会调用acquire()方法这里面会调用tryAcquire()方法去设置state变量如果失败的话就把当前线程放入一个Node中存入队列public final void acquire(int arg) {if (!tryAcquire(arg) acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();}释放资源的时候是调用realase()方法会调用tryRelease()方法修改state变量调用成果后会去唤醒队列中Node里的线程unparkSuccessor()方法就是判断当前state变量是否符合唤醒的标准如果合适就唤醒否则继续放回队列public final boolean release(int arg) {if (tryRelease(arg)) {Node h head;if (h ! null h.waitStatus ! 0)unparkSuccessor(h);return true;}return false;}注意tryAcquire()和tryRelease()方法在AQS中都是空的前面说了JUC中很多同步锁都是基于AQS实现所以加锁和释放锁的逻辑都还不确定因此是要在这些同步锁中实现这两个方法protected boolean tryAcquire(int arg) {throw new UnsupportedOperationException();}protected boolean tryRelease(int arg) {throw new UnsupportedOperationException();}共享式获取资源会调用acquireShared()方法会调用tryAcquireShared()操作state变量如果成功就获取资源失败则放入队列public final void acquireShared(int arg) {if (tryAcquireShared(arg) 0)doAcquireShared(arg);}释放资源是调用releaseShared()方法会调用tryReleaseShared()设置state变量如果成功就唤醒队列中的一个Node里的线程不满足唤醒条件则还放回队列中public final boolean releaseShared(int arg) {if (tryReleaseShared(arg)) {doReleaseShared();return true;}return false;}和独占式一样tryAcquireShared()和tryReleaseShared()也是需要子类来提供protected int tryAcquireShared(int arg) {throw new UnsupportedOperationException();}protected boolean tryReleaseShared(int arg) {throw new UnsupportedOperationException();}条件变量ConditionCondition中的signal()和await()方法类似与notify()和wait()方法需要和AQS锁配合使用。public static void main(String[] args) throws InterruptedException {ReentrantLock lock new ReentrantLock();Condition condition lock.newCondition();Thread thread1 new Thread(new Runnable() {Overridepublic void run() {lock.lock();System.out.println( t1 加锁);System.out.println(t1 start await);try {condition.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(t1 end await);lock.unlock();}});thread1.start();Thread thread2 new Thread(new Runnable() {Overridepublic void run() {lock.lock();System.out.println( t2 加锁);System.out.println(t2 start signal);condition.signal();System.out.println(t2 end signal);lock.unlock();}});thread2.start();}在AQS中的原理上面lock.newCondition()其实是new一个AQS中ConditionObject内部类的对象出来这个对象里面有一个队列当调用await()方法的时候会存入一个Node节点到这个队列中并且调用park()方法阻塞当前线程释放当前线程的锁。而调用singal()方法则会移除内部类中的队列头部的Node然后放入AQS中的队列中等待执行机会同样的AQS并没有实现newCondition()方法也是需要子类自己去实现总结本文内容大部分都是阅读了这本书的内容主要讲了整个AQS的大致原理和几个最重要的方法其实整个AQS的源码是很复杂的但是了解大致原理已经对我们熟悉运用那些JUC中的同步锁有很大的帮助。