java并发之队列同步器

、注:仅根据自己的理解整理的零碎知识点(慢慢补充)

java中同步锁的实现依赖于内部的队列同步器,通过继承实现队列同步器获取同步状态和释放同步状态的方法。

队列同步器内部通过一个int成员变量state来表示同步的状态  占有还是释放(包括共享和独占),当线程获取同步状态失败时当前线程被构造成一个节点加入到同步器的FIFO队列中,同时阻塞当前线程,当同步状态释放时会把首节点的线程唤醒使其再次尝试获取同步状态。同步对列中的节点保存获取同步状态失败的线程引用、等待状态、以及前驱和后继节点。

获取同步状态失败:

同步器中拥有首节点和尾节点,当一个线程成获取同步状态(锁),其他准备获取同步状态的线程便无法获取同步状态,转而被构造成节点加入到同步器的同步队列的尾部。这个过程可能会有多个线程同时请求加入到尾部,需要保证尾节点的插入是原子性的,利用CAS操作来完成。

首节点同步状态释放:

首节点释放同步同步状态后会唤醒后继节点,后集结点获取同步状态成功时会将自己设置为首节点,这个过程中由于只有一个线会成功获取同步状态。因此设置首节点不需要CAS操作来保证。

Condition 实现:

作为同步器的内部类,因为condition的操作需要先获取对应的锁,每个condition独享包括一个等待队列,队列中的每个节点代表了一个等待在该condition对象的线程,获取锁线程执行await()该线程释放锁,构造节点进入等待状态。等待队列节复用了同步队列的节点类型。如果没有先获取同步状态直接调用await()方法,则在释放锁的时候,虽然其节点状态state默认值为0表示获取了同步状态。但由于事先没有该线程获取同步状态的信息在释放时检查到拥有同步状态的线程并非当前线程而抛出异常。(在没有同步的代码块中是不需要获取和释放同步状态的操作的),

protected final boolean tryRelease(int releases) {
    int c = getState() - releases;
    if (Thread.currentThread() != getExclusiveOwnerThread())
        throw new IllegalMonitorStateException();
    boolean free = false;
    if (c == 0) {
        free = true;
        setExclusiveOwnerThread(null);
    }
    setState(c);
    return free;
}
在condition对象中,具有等待队列,队列的尾节点和首节点的添加和删除不需要CAS来保证原子性,因为操作conditon的线程已经获取了锁,通过锁来保证了线程安全性。

你可能感兴趣的:(java)