锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

AbstractQueuedSynchronizer浅析

时间:2022-08-30 11:30:01 axt540224连接器8fu8hu8h8fub传感器fh58m系列fpc连接器1v69连接器7p28k9qk4q连接器mx34r12hf4t连接器

文章目录

      • 简介
      • 如何实现自定义同步器
      • 实现分析
        • 1. public final void acquire(int arg) 该方法以排他的方式获中断不敏感,完成synchronized语义。

简介

  1. 提供抽象类FIFO(先进先出的队列),可用于构建或其他同步装置的基本框架。同步器使用int state表示一种状态。子类通过继续抽象类并实现其管理状态的方法,管理模式是通过 acquire(int arg)方法release(int arg)操作状态的方法。
  • 在多线程环境中,必须确保原子性通过以下方法改变状态
protected final int getState() { 
                 return state;     }  protected final void setState(int newState) { 
             state = newState; } protected final boolean compareAndSetState(int expect, int update) { 
             return unsafe.compareAndSwapInt(this, stateOffset, expect, update); } 
  1. 同步器的开始提到实际上依赖于一个FIFO那么队列中的元素,Node它是一个保存线程引用和线程状态的容器个线程对同步器的访问都可以看作是队列中的一个节点。Node主要包括以下成员变量
static final class Node { 
             /** * 表示节点的状态。包含的状态包括: * CANCELLED,值为1,表示当前线程被取消; * SIGNAL, 值为-1,表示当前节点后继节点中包含的线程需要运行,即unpark; * CONDITION,值为-2,表示当前节点在等待condition,也就是在condition队中; * PROPAGATE,值为-3,表示当前场景下的后续值acquireShared能够执行; 值为0,表示当前节点在sync队列中,等待着获取锁。 */     volatile int waitStatus;      /** * 前驱节点,如当前节点被取消,需要前驱节点和后继节点来完成连接。 */     volatile Node prev;      /** * 后继节点。 */      volatile Node next;      /** * 当前线程进入队列时。 */     volatile Thread thread;     /** *存储condition队列中的后继节点。 */     Node nextWaiter; } 

节点成为sync队列condition队列构建的基础包含在同步器中sync队列。同步器有三个成员变量:sync队列的头结点head、sync队列的尾节点tail和状态state。对于锁的获取,请求形成一个节点并将其挂载在尾部,锁资源的转移(释放和再获取)从头部向后进行。同步器的维护状态state,多线程的获取将产生链结构。
[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-1K72NCUd-1589454196113)(data:image/png;base64,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)]

如何实现自定义同步器

实现自定义同步器时,需要使用同步器提供的getState()、setState()和compareAndSetState()方法来操纵状态的变迁。

方法名称 描述
protected boolean tryAcquire(int arg) 排它的获取这个状态。这个方法的实现需要查询当前状态是否允许获取,然后再进行获取(使用compareAndSetState来做)状态。
protected boolean tryRelease(int arg) 释放状态。
protected int tryAcquireShared(int arg) 共享的模式下获取状态。
protected boolean tryReleaseShared(int arg) 共享的模式下释放状态。
protected boolean isHeldExclusively() 在排它模式下,状态是否被占用。

class Mutex implements Lock, java.io.Serializable { 
        
  // 内部类,自定义同步器
  private static class Sync extends AbstractQueuedSynchronizer { 
        
    // 是否处于占用状态
    protected boolean isHeldExclusively() { 
        
      return getState() == 1;
    }
    // 当状态为0的时候获取锁
    public boolean tryAcquire(int acquires) { 
        
      assert acquires == 1; // Otherwise unused
      if (compareAndSetState(0, 1)) { 
        
        setExclusiveOwnerThread(Thread.currentThread());
        return true;
      }
      return false;
    }
    // 释放锁,将状态设置为0
    protected boolean tryRelease(int releases) { 
        
      assert releases == 1; // Otherwise unused
      if (getState() == 0) throw new IllegalMonitorStateException();
      setExclusiveOwnerThread(null);
      setState(0);
      return true;
    }
    // 返回一个Condition,每个condition都包含了一个condition队列
    Condition newCondition() { 
         return new ConditionObject(); }
  }
  // 仅需要将操作代理到Sync上即可
  private final Sync sync = new Sync();
  public void lock()                { 
         sync.acquire(1); }
  public boolean tryLock()          { 
         return sync.tryAcquire(1); }
  public void unlock()              { 
         sync.release(1); }
  public Condition newCondition()   { 
         return sync.newCondition(); }
  public boolean isLocked()         { 
         return sync.isHeldExclusively(); }
  public boolean hasQueuedThreads() { 
         return sync.hasQueuedThreads(); }
  public void lockInterruptibly() throws InterruptedException { 
        
    sync.acquireInterruptibly(1);
  }
  public boolean tryLock(long timeout, TimeUnit unit)
      throws InterruptedException { 
        
    return sync.tryAcquireNanos(1, unit.toNanos(timeout));
  }
}

实现分析

1. public final void acquire(int arg) 该方法以排他的方式获取锁,对中断不敏感,完成synchronized语义。

  public final void acquire(int arg) { 
        
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

上述逻辑主要包括:

  • 在tryAcquire方法中使用了同步器提供的对state操作的方法,利用compareAndSet保证只有一个线程能够对状态进行成功修改,而没有成功修改的线程将进入sync队列排队。
  • 如果获取不到,将当前线程构造成节点Node并加入sync队列;
  • 进入队列的每个线程都是一个节点Node,从而形成了一个双向队列,类似CLH队列,这样做的目的是线程间的通信会被限制在较小规模(也就是两个节点左右)。
final boolean acquireQueued(final Node node, int arg) { 
        
        boolean failed = true;
        try { 
        
            boolean interrupted = false;
            for (;;) { 
        
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) { 
        
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally { 
        
            if (failed)
                cancelAcquire(node);
        }
    }

上述逻辑主要包括:

  • 获取当前节点的前驱节点;需要获取当前节点的前驱节点,而头结点所对应的含义是当前站有锁且正在运行。
  • 当前驱节点是头结点并且能够获取状态,代表该当前节点占有锁;如果满足上述条件,那么代表能够占有锁,根据节点对锁占有的含义,设置头结点为当前节点。
  • 否则进入等待状态。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oz5BIFBZ-1589454196116)(data:image/png;base64,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

相关文章