Java常见Lock(一): lock之Condition、ConditionObject、LockSupport

lock结构图

图git地址
这里写图片描述

Condition

public interface Condition

  1. Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。
  2. Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。
  3. Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其 newCondition() 方法。
  4. 提供三种形式的条件等待(可中断、不可中断和超时)。
不可中断的条件等待
void awaitUninterruptibly()造成当前线程在接到信号之前一直处于等待状态。
可中断的条件等待
void await() 造成当前线程在接到信号或被中断之前一直处于等待状态。
超时且可中断的条件等待
long awaitNanos(long nanosTimeout) 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
boolean await(long time, TimeUnit unit) 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。。
boolean awaitUntil(Date deadline) 造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。
唤醒
void signal() 唤醒一个等待线程。
void signalAll() 唤醒所有等待线程。

 
Condition一般与Lock结合使用,并由Lock.newCondition进行实例化。

ConditionObject

public class ConditionObject implements Condition, java.io.Serializable

  1. AbstractQueuedSynchronizer和AbstractQueuedLongSynchronizer内部类,实现基本一样。
  2. 实现Condition接口。
  3. Condition 实现是 Lock 实现的基础。
成员变量
public class ConditionObject implements Condition, java.io.Serializable {
        /** Condition等待队列的头结点. */
        private transient Node firstWaiter;
        /** Condition等待队列的尾结点. */
        private transient Node lastWaiter;
        public ConditionObject() { }
}

await:造成当前线程在接到信号或被中断之前一直处于等待状态。

        public final void await() throws InterruptedException {
            if (Thread.interrupted())//判断线程是否被中断
                throw new InterruptedException();
            Node node = addConditionWaiter();//添加到等待队列尾部
            long savedState = fullyRelease(node);//释放结点
            int interruptMode = 0;
            while (!isOnSyncQueue(node)) {//在公平队列中找相应node
                LockSupport.park(this);//禁用当前线程
                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)//判断等待中是否被中断
                    break;
            }
            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                interruptMode = REINTERRUPT;
            if (node.nextWaiter != null)
                unlinkCancelledWaiters();
            if (interruptMode != 0)
                reportInterruptAfterWait(interruptMode);
        }
        /**
         * 以当前线程实例化等待Node添加到等待队列尾部
         */
        private Node addConditionWaiter() {
            Node t = lastWaiter;
            // If lastWaiter is cancelled, clean out.
            if (t != null && t.waitStatus != Node.CONDITION) {
                unlinkCancelledWaiters();
                t = lastWaiter;
            }
            Node node = new Node(Thread.currentThread(), Node.CONDITION);
            if (t == null)
                firstWaiter = node;
            else
                t.nextWaiter = node;
            lastWaiter = node;
            return node;
        }

具有超时特性的await方法大体和上面相同,只是加入了时间戳或者时长来判断是否超时。

 

signal():唤醒一个等待线程。
signalAll() :唤醒所有等待线程。

        public final void signal() {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            Node first = firstWaiter;
            if (first != null)
                doSignal(first);
        }
        /**
         * 唤醒等待队列中的头结点
         */
        private void doSignal(Node first) {
            do {
                if ( (firstWaiter = first.nextWaiter) == null)
                    lastWaiter = null;
                first.nextWaiter = null;
            } while (!transferForSignal(first) &&
                     (first = firstWaiter) != null);
        }
        
        /**
         * 循环唤醒等待队列中的所有结点
         */
        private void doSignalAll(Node first) {
            lastWaiter = firstWaiter  = null;
            do {
                Node next = first.nextWaiter;
                first.nextWaiter = null;
                transferForSignal(first);
                first = next;
            } while (first != null);
        }
    /**
     * 将等待线程Node转移到sync队列中,并使其可用
     */
    final boolean transferForSignal(Node node) {
        if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
            return false;
        Node p = enq(node);
        int ws = p.waitStatus;
        if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL)) 
            LockSupport.unpark(node.thread);
        return true;
    }

从源码中看到Condition的实现类ConditionObject阻塞或者唤醒线程使用了一个核心支持类:LockSupport。

LockSupport

public class LockSupport

  1. 用来创建锁和其他同步类的基本线程阻塞原语。
  2. 一个帮助类,提供的方法均是静态方法。
  3. 利用UnSafe进行原子操作。
提供的方法
Object getBlocker(Thread t) 返回提供给最近一次尚未解除阻塞的 park 方法调用的 blocker 对象,如果该调用不受阻塞,则返回 null。
void park() 为了线程调度,禁用当前线程,除非许可可用。
void park(Object blocker) 为了线程调度,在许可可用之前禁用当前线程。
void parkNanos(long nanos) 为了线程调度禁用当前线程,最多等待指定的等待时间,除非许可可用。
void parkNanos(Object blocker, long nanos) 为了线程调度,在许可可用前禁用当前线程,并最多等待指定的等待时间。
void parkUntil(long deadline) 为了线程调度,在指定的时限前禁用当前线程,除非许可可用。
void parkUntil(Object blocker, long deadline) 为了线程调度,在指定的时限前禁用当前线程,除非许可可用。
void unpark(Thread thread) 如果给定线程的许可尚不可用,则使其可用。

AbstractOwnableSynchronizer

public abstract class AbstractOwnableSynchronizer implements java.io.Serializable

  1. 可以由线程以独占方式拥有的同步器。
  2. 为创建锁和相关同步器(伴随着所有权的概念)提供了基础。
  3. AbstractOwnableSynchronizer 类本身不管理或使用此信息。但是,子类和工具可以使用适当维护的值帮助控制和监视访问以及提供诊断。
方法
void setExclusiveOwnerThread(Thread t) 设置当前拥有独占访问的线程。
Thread getExclusiveOwnerThread() 返回由 setExclusiveOwnerThread 最后设置的线程;如果从未设置,则返回 null。

AbstractQueuedSynchronizer

public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable

  1. 为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关同步器(信号量、事件,等等)提供一个框架。
  2. 此类的设计目标是成为依靠单个原子 int 值来表示状态的大多数同步器的一个有用基础。
  3. 子类必须定义更改此状态的受保护方法,并定义哪种状态对于此对象意味着被获取或被释放。假定这些条件之后,此类中的其他方法就可以实现所有排队和阻塞机制。
  4. 此类支持默认的独占 模式和共享 模式之一,或者二者都支持。
  5. ReentrantLock和ReentrantReadWriteLock内部类Sync的父类。
  6. 定义了内部类ConditionObject。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值