jdk7 AbstractQueuedSynchronizer(AQS) 应用分析
发布日期:2021-09-08 03:38:41 浏览次数:7 分类:技术文章

本文共 13267 字,大约阅读时间需要 44 分钟。

hot3.png

//先拿ReentrantLock分析看看public class ReentrantLock implements Lock, java.io.Serializable {    private static final long serialVersionUID = 7373984872572414699L;    /** Synchronizer providing all implementation mechanics */    private final Sync sync;//获取锁,和释放锁,都是变量操作    /**     * Base of synchronization control for this lock. Subclassed     * into fair and nonfair versions below. Uses AQS state to     * represent the number of holds on the lock. Sync 继承自AbstractQueuedSynchronizer(所谓AQS)     * 这个Sync是个抽象类,下面公平锁FairSync和非公平锁NonfairSync会实现它     */    abstract static class Sync extends AbstractQueuedSynchronizer {        private static final long serialVersionUID = -5179523762034025860L;        /**         * Performs {@link Lock#lock}. The main reason for subclassing         * is to allow fast path for nonfair version.         */        abstract void lock();//等着公平锁和非公平锁的实现        /**         * Performs non-fair tryLock.  tryAcquire is         * implemented in subclasses, but both need nonfair         * try for trylock method.尝试获取锁         */        final boolean nonfairTryAcquire(int acquires) {            final Thread current = Thread.currentThread();            int c = getState();//是它,就是它,来获取【依赖状态变量】,锁的根基变量            if (c == 0) {                if (compareAndSetState(0, acquires)) {//是它,就是它,通过cas原则更新【依赖状态变量】,锁的根基方法,更新成功了,可理解是获取锁成功,更新失败了,就算获取锁失败(jdk里本没有锁)                    setExclusiveOwnerThread(current);//设置当前线程为 排他的所有者                    return true;                }            }            else if (current == getExclusiveOwnerThread()) {//如果当前线程已经是所有者了                int nextc = c + acquires;//增加 状态变量值                if (nextc < 0) // overflow                    throw new Error("Maximum lock count exceeded");                setState(nextc);//是它,就是它,更新 【依赖状态变量】                return true;            }            return false;        }       //释放锁        protected final boolean tryRelease(int releases) {            int c = getState() - releases;//减少 状态变量值            if (Thread.currentThread() != getExclusiveOwnerThread())//当前线程是锁的拥有者线程吗?                throw new IllegalMonitorStateException();            boolean free = false;            if (c == 0) {//如果没有线程拥有锁,就设置null                free = true;                setExclusiveOwnerThread(null);            }            setState(c);            return free;        }        //是否被当前线程拥有        protected final boolean isHeldExclusively() {            // While we must in general read state before owner,            // we don't need to do so to check if current thread is owner            return getExclusiveOwnerThread() == Thread.currentThread();        }        //题外话:显示锁,多等待队列实现(其实就是new 个新对象,归根结底,还是一个对象,一个条件队列)        final ConditionObject newCondition() {            return new ConditionObject();        }        // Methods relayed from outer class        final Thread getOwner() {            return getState() == 0 ? null : getExclusiveOwnerThread();        }        final int getHoldCount() {            return isHeldExclusively() ? getState() : 0;        }        final boolean isLocked() {            return getState() != 0;        }        /**	 *  从一个输入流重构锁。这个怎么玩的炫?         * Reconstitutes this lock instance from a stream.         * @param s the stream         */        private void readObject(java.io.ObjectInputStream s)            throws java.io.IOException, ClassNotFoundException {            s.defaultReadObject();            setState(0); // reset to unlocked state        }    }    /**     * Sync object for non-fair locks     * 非公平锁的实现     */    static final class NonfairSync extends Sync {        private static final long serialVersionUID = 7316153563782823691L;        /**         * Performs lock.  Try immediate barge, backing up to normal         * acquire on failure. 尝试获取锁         */        final void lock() {//调的还是AQS里的方法,所以说AQS是根基类            if (compareAndSetState(0, 1))                setExclusiveOwnerThread(Thread.currentThread());            else                acquire(1);//这个方法是AQS里的方法,但它又回调子类tryAcquire(int arg)方法,也就是下面的tryAcquire方法,也就是模板方法模式,AQS负责流程调度,具体每个锁的获取,失败语义,自己定义。        }        protected final boolean tryAcquire(int acquires) {            return nonfairTryAcquire(acquires);        }    }    /**     * Sync object for fair locks     * 公平锁,(弄个队列FIFO)     */    static final class FairSync extends Sync {        private static final long serialVersionUID = -3000897897090466540L;        final void lock() {            acquire(1);        }        /**         * Fair version of tryAcquire.  Don't grant access unless         * recursive call or no waiters or is first.         */        protected final boolean tryAcquire(int acquires) {            final Thread current = Thread.currentThread();            int c = getState();            if (c == 0) {                if (!hasQueuedPredecessors() &&//没有在前面等待的线程,(体现公平性),并且compareAndSetState 成功,就获取锁成功了。                    compareAndSetState(0, acquires)) {                    setExclusiveOwnerThread(current);                    return true;                }            }            else if (current == getExclusiveOwnerThread()) {//若果当前线程,已经获取锁了,就更新,【状态变量值】                int nextc = c + acquires;                if (nextc < 0)                    throw new Error("Maximum lock count exceeded");                setState(nextc);                return true;            }            return false;        }    }    /**     * Creates an instance of {@code ReentrantLock}.     * This is equivalent to using {@code ReentrantLock(false)}.默认是非公平锁     */    public ReentrantLock() {        sync = new NonfairSync();    }    /**     * Creates an instance of {@code ReentrantLock} with the     * given fairness policy.     * 可以构造非公平和公平锁     * @param fair {@code true} if this lock should use a fair ordering policy     */    public ReentrantLock(boolean fair) {        sync = fair ? new FairSync() : new NonfairSync();    }    /**     * Acquires the lock.     *     * 

Acquires the lock if it is not held by another thread and returns * immediately, setting the lock hold count to one. * *

If the current thread already holds the lock then the hold * count is incremented by one and the method returns immediately. * *

If the lock is held by another thread then the * current thread becomes disabled for thread scheduling * purposes and lies dormant until the lock has been acquired, * at which time the lock hold count is set to one. */ public void lock() { sync.lock(); } /** * Acquires the lock unless the current thread is * {@linkplain Thread#interrupt interrupted}. * *

Acquires the lock if it is not held by another thread and returns * immediately, setting the lock hold count to one. * *

If the current thread already holds this lock then the hold count * is incremented by one and the method returns immediately. * *

If the lock is held by another thread then the * current thread becomes disabled for thread scheduling * purposes and lies dormant until one of two things happens: * *

    * *
  • The lock is acquired by the current thread; or * *
  • Some other thread {@linkplain Thread#interrupt interrupts} the * current thread. * *
* *

If the lock is acquired by the current thread then the lock hold * count is set to one. * *

If the current thread: * *

    * *
  • has its interrupted status set on entry to this method; or * *
  • is {@linkplain Thread#interrupt interrupted} while acquiring * the lock, * *
* * then {@link InterruptedException} is thrown and the current thread's * interrupted status is cleared. * *

In this implementation, as this method is an explicit * interruption point, preference is given to responding to the * interrupt over normal or reentrant acquisition of the lock. * * @throws InterruptedException if the current thread is interrupted */ public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } /** * Acquires the lock only if it is not held by another thread at the time * of invocation. * *

Acquires the lock if it is not held by another thread and * returns immediately with the value {@code true}, setting the * lock hold count to one. Even when this lock has been set to use a * fair ordering policy, a call to {@code tryLock()} will * immediately acquire the lock if it is available, whether or not * other threads are currently waiting for the lock. * This "barging" behavior can be useful in certain * circumstances, even though it breaks fairness. If you want to honor * the fairness setting for this lock, then use * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) } * which is almost equivalent (it also detects interruption). * *

If the current thread already holds this lock then the hold * count is incremented by one and the method returns {@code true}. * *

If the lock is held by another thread then this method will return * immediately with the value {@code false}. * * @return {@code true} if the lock was free and was acquired by the * current thread, or the lock was already held by the current * thread; and {@code false} otherwise * 通过sync获取锁,默认是非公平的。 */ public boolean tryLock() { return sync.nonfairTryAcquire(1); } /** * Acquires the lock if it is not held by another thread within the given * waiting time and the current thread has not been * {@linkplain Thread#interrupt interrupted}. * *

Acquires the lock if it is not held by another thread and returns * immediately with the value {@code true}, setting the lock hold count * to one. If this lock has been set to use a fair ordering policy then * an available lock will not be acquired if any other threads * are waiting for the lock. This is in contrast to the {@link #tryLock()} * method. If you want a timed {@code tryLock} that does permit barging on * a fair lock then combine the timed and un-timed forms together: * *

if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }     * 
* *

If the current thread * already holds this lock then the hold count is incremented by one and * the method returns {@code true}. * *

If the lock is held by another thread then the * current thread becomes disabled for thread scheduling * purposes and lies dormant until one of three things happens: * *

    * *
  • The lock is acquired by the current thread; or * *
  • Some other thread {@linkplain Thread#interrupt interrupts} * the current thread; or * *
  • The specified waiting time elapses * *
* *

If the lock is acquired then the value {@code true} is returned and * the lock hold count is set to one. * *

If the current thread: * *

    * *
  • has its interrupted status set on entry to this method; or * *
  • is {@linkplain Thread#interrupt interrupted} while * acquiring the lock, * *
* then {@link InterruptedException} is thrown and the current thread's * interrupted status is cleared. * *

If the specified waiting time elapses then the value {@code false} * is returned. If the time is less than or equal to zero, the method * will not wait at all. * *

In this implementation, as this method is an explicit * interruption point, preference is given to responding to the * interrupt over normal or reentrant acquisition of the lock, and * over reporting the elapse of the waiting time. * * @param timeout the time to wait for the lock * @param unit the time unit of the timeout argument * @return {@code true} if the lock was free and was acquired by the * current thread, or the lock was already held by the current * thread; and {@code false} if the waiting time elapsed before * the lock could be acquired * @throws InterruptedException if the current thread is interrupted * @throws NullPointerException if the time unit is null * 通过sync,获取锁,可中断,可超时 */ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(timeout)); } /** * Attempts to release this lock. * *

If the current thread is the holder of this lock then the hold * count is decremented. If the hold count is now zero then the lock * is released. If the current thread is not the holder of this * lock then {@link IllegalMonitorStateException} is thrown. * * @throws IllegalMonitorStateException if the current thread does not * hold this lock */ public void unlock() {//这里的release方法其实也是AQS的一个模板方法,会回调子类的tryRelease(int arg)方法。 sync.release(1); } // 其他代码省略几百行。。。。 }

    然后翻翻jdk源码 会发现 ReentrantReadWriteLock ,CountDownLatch,Semaphore 也是AQS实现的

    下面看看https://my.oschina.net/u/146130/blog/881848

转载于:https://my.oschina.net/u/146130/blog/877357

转载地址:https://blog.csdn.net/weixin_34313182/article/details/91979919 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:NIO 入门
下一篇:vncserver配置注意

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年03月14日 09时53分53秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

oracle 坏块查找,检测oracle数据库坏块的方法 2019-04-21
怎么对oracle 进行重装,重装oracle的方法 2019-04-21
oracle将memory_target改为自动管理方式,Oracle 11g新特性:Memory_target与自动内存管理... 2019-04-21
entlib连接oracle乱码,Connecting Oracle using ODP.NET with Enterprise Library DAAB 2019-04-21
php eol 没有换行,php_eol没有换行怎么办 2019-04-21
oracle sql plan baseline,sql plan baseline使用心得 2019-04-21
oracle历史数据归档工具,济南钢铁利用数据库归档工具提升Oracle数据库应用性能... 2019-04-21
oracle数据对象缓存,oracle优化缓存对象与数据 -电脑资料 2019-04-21
linux系统如何连接wf,Linux下如何通过命令连接wifi 2019-04-21
linux网卡传输数据卡死,linux – 网卡正在接收,但根本没有传输? 2019-04-21
红旗linux备份,更换红旗Linux: Asianux的yum源为网易源 2019-04-21
如何用php直接渲染页面,总结浏览器渲染页面的方法 2019-04-21
redis sharding java,简单了解redis常见客户端及Sharding机制原理 2019-04-21
php实现微信小程序推送,实现微信小程序模板消息不受限制、无限主动推送 2019-04-21
java水面倒影效果,Java:图像倒影 2019-04-21
horde groupware php,Horde 3.3.12后门任意PHP代码执行漏洞 2019-04-21
php是一种通用开源,caozha-admin(PHP网站后台管理框架) 2019-04-21
php队列的数据表有哪些字段,php 数据结构之链表队列 2019-04-21
404怎么解决java,HTTP Status 404如何解决 2019-04-21
java查找公共子串,查找两个串的最大公共子串 2019-04-21