判断release模式_AbstractQueuedSynchronizer (AQS)以及模板设计模式1

如果内容有错误或者您有不同的见解,请关注我。想要思维导图的小伙伴们记得留言哦。

e17169d0b21305c5517d0fce092d738d.png

c5d671a97412648b934112fb737b2184.png

/** * Provides a framework for implementing blocking locks and related * synchronizers (semaphores, events, etc) that rely on * first-in-first-out (FIFO) wait queues.  This class is designed to * be a useful basis for most kinds of synchronizers that rely on a * single atomic {@code int} value to represent state. Subclasses * must define the protected methods that change this state, and which * define what that state means in terms of this object being acquired * or released.  Given these, the other methods in this class carry * out all queuing and blocking mechanics. Subclasses can maintain * other state fields, but only the atomically updated {@code int} * value manipulated using methods {@link #getState}, {@link * #setState} and {@link #compareAndSetState} is tracked with respect * to synchronization.

【翻译】该类提供了一个实现阻塞锁和相关异步器(信号量,事件等)的框架,该类依赖于FIFO(先进先出)的队列。这个类对那些依赖与单一的原子的int值来作为状态的异步器来说是一个有用的基础类。子类必须(注意是必须)定义受保护的方法来改变state的值,并且这个子类定义的这个state的状态意味着子类对象的获取或释放。

【理解】子类实现这个类之后,实现了一些方法,这些方法中可以操作这个state变量,这个变量的的状态意味着这个类是获取了还是释放了这个state变量。如果是state=0表示我们没有获取到该变量,当前线程放入到FIFO队列中。如果state=1表示我获取到了state,可以执行后续操作。

【翻译】已经给出的这些类以及这个类中的其他的方法执行所有的队列和阻塞指令。子类可以维护其他的状态字段,但是只有这个通过getState、setState和compareAndSetState方法来原子操作的int值,会被有关的同步跟踪。

【理解】我们可以自定义状态字段,但是在同步类的实现中我们只需要跟踪int value就好了,只要知道这个int的值,我们就可以判断是当前线程是否获得了锁,至此可以判断是否将当前线程放入队列去等待。

 * 

Subclasses should be defined as non-public internal helper

* classes that are used to implement the synchronization properties * of their enclosing class. Class * {@code AbstractQueuedSynchronizer} does not implement any * synchronization interface. Instead it defines methods such as * {@link #acquireInterruptibly} that can be invoked as * appropriate by concrete locks and related synchronizers to * implement their public methods.

【翻译】子类在实现时需要定义一个非公共的内部帮助类来实现这个子类封装的异步属性。AbstractQueuedSynchronizer这个类不需要实现任何同步接口,相反AbstractQueuedSynchronizer定义了像acquireInterruptibly的方法可以根据具体锁和相关的异步器来调用的情况也可以实现他的的公共方法。

【理解】子类实现AQS方法的时候可以定义一个帮助类来实现AQS中的方法。AQS不实现任何实现异步的方法,但是AQS中的一些其他方法是可以实现公共方法的,像acquireInterruptibly这个方法。

 * 

This class supports either or both a default <em>exclusive</em>

* mode and a shared mode. When acquired in exclusive mode, * attempted acquires by other threads cannot succeed. Shared mode * acquires by multiple threads may (but need not) succeed. This class * does not "understand" these differences except in the * mechanical sense that when a shared mode acquire succeeds, the next * waiting thread (if one exists) must also determine whether it can * acquire as well. Threads waiting in the different modes share the * same FIFO queue. Usually, implementation subclasses support only * one of these modes, but both can come into play for example in a * {@link ReadWriteLock}. Subclasses that support only exclusive or * only shared modes need not define the methods supporting the unused mode.

【翻译】这个类即支持默认的排他(独占)模式也支持共享模式。当使用独占模式获取这个类时,其他线程要想也获取这个类就会失败。共享(就是多个线程同时获取这个类)模式获取该类时可能成功。除了在机器意义上,这个类根部不理解这些不同(就是这类本部不理解独占模式和共享模式是啥玩意)。当一个线程在共享模式上获取锁成功,如果有第二个等待的线程,也来获取该类的锁,那么这个线程必须准确知道是否可以获取。在不同模式中等待的线程共享相同的先进先出队列。通常情况下我们实现这个类仅仅支持其中的一个模式(就是说要么是共享的模式,要么排他的模式)但是两者也都可以同时实现,例如在ReadWriteLock中。仅支持一个排他锁或者共享锁模式的子类就没有必要定义其他无用的模式中的方法了。

 * 

This class defines a nested {@link ConditionObject} class that

* can be used as a {@link Condition} implementation by subclasses * supporting exclusive mode for which method {@link * #isHeldExclusively} reports whether synchronization is exclusively * held with respect to the current thread, method {@link #release} * invoked with the current {@link #getState} value fully releases * this object, and {@link #acquire}, given this saved state value, * eventually restores this object to its previous acquired state. No * {@code AbstractQueuedSynchronizer} method otherwise creates such a * condition, so if this constraint cannot be met, do not use it. The * behavior of {@link ConditionObject} depends of course on the * semantics of its synchronizer implementation.

这个类定义了一个嵌套的ConditionObject(条件对象)的类,这个条件对象可以用来实现Condition,如何实现呢?通过支持排他模式的子类,这个子类的方法isHeldExclusively(是否拥有排他锁)(表明、表示)同步是否被当前的相关线程占有,当前(getState)value调用release方法来完全释放当前对象,最终它会将这个对象还原成它之前获取的到的那个状态。除非创建这样一个condition,否则就没有抽象队列异步器方法,如果这个限制条件不能满足,就不要使用ConditionObject了。ConditionObject的方法当然也依赖实现他的语义。

* 

This class provides inspection, instrumentation, and monitoring

* methods for the internal queue, as well as similar methods for * condition objects. These can be exported as desired into classes * using an {@code AbstractQueuedSynchronizer} for their * synchronization mechanics. * *

Serialization of this class stores only the underlying atomic

* integer maintaining state, so deserialized objects have empty * thread queues. Typical subclasses requiring serializability will * define a {@code readObject} method that restores this to a known * initial state upon deserialization. * *

Usage

* *

To use this class as the basis of a synchronizer, redefine the

* following methods, as applicable, by inspecting and/or modifying * the synchronization state using {@link #getState}, {@link * #setState} and/or {@link #compareAndSetState}: * * * {@link #tryAcquire} * {@link #tryRelease} * {@link #tryAcquireShared} * {@link #tryReleaseShared} * {@link #isHeldExclusively} *

【翻译】这个类为这个内部的队列提供了检查、检测和监控方法,如果需要的话,可以使用AQS导入到他们自己同步语义中。

这个类的序列化存储仅仅存储基本的原子的整型来维护状态,所以反序列化对象时会得到一个空的线程队列。需要反序列化的典型的子类需要定义一个readObject方法,用来根据反序列化将其恢复到一个已知的初始化状态。

【用法】这个类作为一个同步器的基础,重新定义以下方法,如果适用的话,可以通过以下三个方法来检测或者修改同步状态:getStaet、setState、compareAndSetState

 * Each of these methods by default throws {@link * UnsupportedOperationException}.  Implementations of these methods * must be internally thread-safe, and should in general be short and * not block. Defining these methods is the only supported * means of using this class. All other methods are declared * {@code final} because they cannot be independently varied. * * 

You may also find the inherited methods from {@link

* AbstractOwnableSynchronizer} useful to keep track of the thread * owning an exclusive synchronizer. You are encouraged to use them * -- this enables monitoring and diagnostic tools to assist users in * determining which threads hold locks.

【翻译】每一个方法默认都出抛出UnsupportedOperationException异常,这些方法的实现必须是内部线程安全的,并且通常情况下还要简单非阻塞的。定义这些方法是使用这个类唯一支持的意义所在(就是说声明了这些类就去实现吧,不是实现我声明这个方法还有什么意义呢,哈哈)。其他所有的方法都被声明为final,因为这个些方法不能单独地修改。(final当然不想让你修改。)

你也能也会发现从AQS继承来的方法,对于拥有排他同步的线程保持追踪也是有用的(可以根据排他锁来查询到当前线程是否拥有锁)。我们建议使用他们,这些方法可以让监控和诊断工具能够判断出哪一个线程有用当前锁。

Even though this class is based on an internal FIFO queue, it

* does not automatically enforce FIFO acquisition policies. The core * of exclusive synchronization takes the form: * *
* Acquire: * while (!tryAcquire(arg)) { * enqueue thread if it is not already queued; * possibly block current thread; * } * * Release: * if (tryRelease(arg)) * unblock the first queued thread; * * (Shared mode is similar but may involve cascading signals.)

【翻译】尽管当前类是基于内部的一个先进行出队列,它也不会自动地强制执行先进先出收集策略,排他的同步核心如下形式。

获取:如果获取不成功,如果当前线程不在队列中,入队列。阻塞当前线程。

释放:如果能释放,释放之后,解锁队列中的第一个线程。

共享模式也这个相同,只是包含了一些级联信号。(为什么说是级联的信号呢,就是说共享模式下,我们可能要定义大于1的状态值或者多个状态int,这些状态int变量之间都是相互影响的。)

【理解】整个类都是依靠这两个方法来实现的,如果拿不到锁,就去等待队列等待。等到拥有锁的线程释放锁之后,解锁队列中的第一个等待的线程。

 * 

This class provides an efficient and scalable basis for

* synchronization in part by specializing its range of use to * synchronizers that can rely on {@code int} state, acquire, and * release parameters, and an internal FIFO wait queue. When this does * not suffice, you can build synchronizers from a lower level using * {@link java.util.concurrent.atomic atomic} classes, your own custom * {@link java.util.Queue} classes, and {@link LockSupport} blocking * support.

【翻译】这个类为同步提供一个有效且可扩展的基础,可以分为以下几点,专业化其使用范围供依赖int状态的同步器使用,获取和释放参数以及内部先进先出等待队列。当这个基础不满足需要时,你可以使用一个底层的atomic类、自定义的类或者支持阻塞的LockSupport类来创建同步器。

【理解】如果这个队列和state的状态不能满足你的需要,你还是可以使用atomic,queue,lockSupport来实现自己的同步器,其实当前类就是这三个类来实现的,道理都是一样的。

 * 

Usage Examples

* *

Here is a non-reentrant mutual exclusion lock class that uses

* the value zero to represent the unlocked state, and one to * represent the locked state. While a non-reentrant lock * does not strictly require recording of the current owner * thread, this class does so anyway to make usage easier to monitor. * It also supports conditions and exposes some instrumentation methods:

【用法实例】这是一个不可重复进入的相互之间排他的锁,这个类使用0这个值来表示解锁状态,1这个值表示加锁状态。虽然不可重复进入的锁不严格要求记录当前拥有锁的线程,但是这类的用法绝对会使监控(监控状态和线程)更加简单。它还支持条件方法和暴露出一些检测方法。

 * 
 {@code
* class Mutex implements Lock, java.io.Serializable { * * // Our internal helper class(内部实现的帮助类,之前介绍过) * private static class Sync extends AbstractQueuedSynchronizer { * // Acquires the lock if state is zero * public boolean tryAcquire(int acquires) { * assert acquires == 1; // Otherwise unused,如果是1表示可以使用,否不不可以使用 * if (compareAndSetState(0, 1)) { * setExclusiveOwnerThread(Thread.currentThread());// 设置当前拥有锁的线程。 * return true; * } * return false; * } * * // Releases the lock by setting state to zero // 通过将state的改为0来表示释放锁 * protected boolean tryRelease(int releases) { * assert releases == 1; // Otherwise unused * if (!isHeldExclusively()) * throw new IllegalMonitorStateException();// 不拥有锁的线程释放这个state状态会抛异常 * setExclusiveOwnerThread(null); //如果成功则设置当前拥有锁的线程为空 * setState(0);//设置状态为0 * return true; * } * * // Reports whether in locked state // 报告锁状态是否可用 * public boolean isLocked() { * return getState() != 0; * } * * public boolean isHeldExclusively() { // 判断当前线程是否拥有锁 * // a data race, but safe due to out-of-thin-air guarantees * return getExclusiveOwnerThread() == Thread.currentThread(); * } * * // Provides a Condition // 提供条件 * public Condition newCondition() { * return new ConditionObject(); * } * * // Deserializes properly // 反序列化state属性,这和之前说的一样,从readObject中读取state即可。 * private void readObject(ObjectInputStream s) * throws IOException, ClassNotFoundException { * s.defaultReadObject(); * setState(0); // reset to unlocked state * } * }
 * 

Here is a latch class that is like a

* {@link java.util.concurrent.CountDownLatch CountDownLatch} * except that it only requires a single {@code signal} to * fire. Because a latch is non-exclusive, it uses the {@code shared} * acquire and release methods. * *
 {@code
* class BooleanLatch { * * private static class Sync extends AbstractQueuedSynchronizer { * boolean isSignalled() { return getState() != 0; } * * protected int tryAcquireShared(int ignore) { * return isSignalled() ? 1 : -1; * } * * protected boolean tryReleaseShared(int ignore) { * setState(1); * return true; * } * } * * private final Sync sync = new Sync(); * public boolean isSignalled() { return sync.isSignalled(); } * public void signal() { sync.releaseShared(1); } * public void await() throws InterruptedException { * sync.acquireSharedInterruptibly(1); * } * }}

上面的列子是排他锁,那么这个就是闩锁,可以定义state>1,当然这个可以自由指定。比如CountDownLatch,除了需要一个唯一的信号来释放之外(就是通知其他线程)因为闩锁是非排他的(就是是共享的呗),闩锁中的获取和释放方法都是共享的(很多线程可以同时使用)。

同样内部类实现AQS,实现继承方法,我们可以通过await方法来让线程等待,等到什么时候呢?等到有一个线程调用了signal方法来释放了这个共享变量。

@author Doug Lea

这就是这个类的作者,记住他,绝对的大神。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值