美文网首页
AQS源码浅析(4)——API

AQS源码浅析(4)——API

作者: 墨_0b54 | 来源:发表于2022-04-06 19:44 被阅读0次

tryAcquire独占模式获取锁

  • 由子类实现,必须支持独占模式
  • 应该检查state值,查看锁对象是否允许以独占模式获取锁
  • 总是由执行获取锁方法的线程调用
  • 如果返回false,获取锁的方法可能会让线程进入同步队列,直到其他线程发出唤醒信号
protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
}

tryRelease独占模式释放锁

  • 由子类实现,必须支持独占模式
  • 尝试设置state值,以独占模式释放锁
  • 这个方法总是由执行释放锁方法的线程调用
  • 锁对象完全释放后返回true,此时任何等待的线程都可以尝试加锁
protected boolean tryRelease(int arg) {
    throw new UnsupportedOperationException();
}

tryAcquireShared共享模式获取锁

  • 由子类实现,必须支持共享模式
  • 应该检查state值,查看锁对象是否允许以共享模式获取锁
  • 如果返回false,获取锁的方法可能会让线程进入同步队列,直到其他线程发出唤醒信号
  • 失败返回负值;
  • 如果以共享模式获取成功但后续共享模式获取不能成功,则为零;
  • 如果以共享模式获取成功且后续共享模式获取也可能成功,则为正值。
  • 在这种情况下,后续等待线程必须检查可用性。
protected int tryAcquireShared(int arg) {
    throw new UnsupportedOperationException();
}

tryReleaseShared共享模式释放锁

  • 由子类实现,必须支持共享模式
  • 尝试设置state值,以共享模式释放锁
  • 这个方法总是由执行释放锁方法的线程调用
protected boolean tryReleaseShared(int arg) {
    throw new UnsupportedOperationException();
}

acquire独占加锁忽略中断

  • 以独占模式加锁,忽略中断
    +即使获取锁过程中被中断,不会抛中断异常,会继续正常运行,但是线程的中断标志还在
  • 通过至少调用一次tryAcquire来实现,true时直接返回
  • 调用一次tryAcquire失败,线程将排队,可能重复阻塞和唤醒,直到tryAcquire调用成功
public final void acquire(int arg) { 
        if (!tryAcquire(arg) && //尝试加锁一次,成功直接退出,否则排队
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) //线程入同步队列排队,反复阻塞和唤醒直到成功
            selfInterrupt(); //获取锁过程中被中断,重新标志线程中断
}
static void selfInterrupt() {
        Thread.currentThread().interrupt();
}

release独占模式释放锁

  • 独占模式释放锁
  • 如果tryRelease返回true,会唤醒一个或多个后继线程
public final boolean release(int arg) { //当前持有锁的线程释放锁并唤醒后继
    if (tryRelease(arg)) { //tryRelease返回ture代表完全释放锁
        Node h = head;
        if (h != null && h.waitStatus != 0) //唤醒同步队列的后继线程
            unparkSuccessor(h);
        return true;
    }
    return false;
}

acquireShared共享模式获取锁忽略中断

  • 以共享模式获取,忽略中断。
  • 通过首先调用至少一次tryAcquireShared来实现,不小于0代表成功,直接返回。
  • 否则线程排队,可能重复阻塞和解除阻塞,直到调用tryAcquireShared成功。
public final void acquireShared(int arg) {
    if (tryAcquireShared(arg) < 0)
        doAcquireShared(arg);
}

releaseShared共享模式释放锁

  • 以共享模式释放锁
  • 如果tryReleaseShared返回 true,唤醒一个或多个后继线程
public final boolean releaseShared(int arg) {
    if (tryReleaseShared(arg)) {
        doReleaseShared();
        return true;
    }
    return false;
}

acquireInterruptibly与acquireSharedInterruptibly,获取锁中断即中止

acquireInterruptibly基本实现同acquire,区别是如果acquireInterruptibly获取锁过程中被中断,会直接抛中断异常,退出同步队列

public final void acquireInterruptibly(int arg) 
        throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    if (!tryAcquire(arg))
        doAcquireInterruptibly(arg);
}

acquireSharedInterruptibly基本实现同acquireShared,区别是如果acquireSharedInterruptibly获取锁过程中被中断,会直接抛中断异常,退出同步队列

public final void acquireSharedInterruptibly(int arg)
        throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    if (tryAcquireShared(arg) < 0)
        doAcquireSharedInterruptibly(arg);
}

tryAcquireNanos与tryAcquireSharedNanos

tryAcquireNanos基本实现同acquireInterruptibly,区别是tryAcquireNanos会返回结果成功或失败,如果超时,退出同步队列并返回false

public final boolean tryAcquireNanos(int arg, long nanosTimeout)
        throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    return tryAcquire(arg) ||
        doAcquireNanos(arg, nanosTimeout);
}

tryAcquireSharedNanos基本实现同acquireInterruptibly,区别是tryAcquireSharedNanos会返回结果成功或失败,如果超时,退出同步队列并返回false

public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
        throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    return tryAcquireShared(arg) >= 0 ||
        doAcquireSharedNanos(arg, nanosTimeout);
}

相关文章

网友评论

      本文标题:AQS源码浅析(4)——API

      本文链接:https://www.haomeiwen.com/subject/uinrsrtx.html