【HikariCP】【SuspendResumeLock】源码学习

Hikari目前已经是springboot的默认数据库连接池,并且以高效和轻量著称,因为代码量比较少,所以可以阅读一下,学习一下,github地址:HikariCP

SuspendResumeLock

数据库连接池暂停恢复锁。如果hikari配置中设置isAllowPoolSuspension为true,那么就会在HikariPool中实例一个暂停恢复锁。

空锁

public static final SuspendResumeLock FAUX_LOCK = new SuspendResumeLock(false) {
  @Override
  public void acquire() {}

  @Override
  public void release() {}

  @Override
  public void suspend() {}

  @Override
  public void resume() {}
};

类中首先创建了一个单例空锁,中间没有实现任何方法,这个对象是用在连接池不需要暂停恢复锁时传入的对象。

成员变量

  • private static final int MAX_PERMITS = 10000;
    信号量最大值为10K

  • private final Semaphore acquisitionSemaphore;
    这个Semaphore信号量在当时阅读《JAVA并发编程实战》中看到过,笔记描述为:

Semaphore中管理着一组虚拟的许可(permit),许可的初始数量可通过构造函数来指定,在执行操作时可以首先获取许可(只要还有剩余的许可),并在使用以后释放许可。如果没有许可,那么acquire将阻塞直到有许可(或者直到被中断或者操作超时)。release方法将返回一个许可给信号量。计算信号量的一种简化形式是二值信号量,即初始值为1的Semaphore。二值信号量可以用做互斥体(mutex),并具备不可重入的加锁语义:谁拥有这个唯一的许可,谁就拥有了互斥锁。

release返回许可信号量的实现不包含真正的许可对象,而且Semaphore也不会将许可和线程关联起来,因此在一个线程中获取的许可可以在另一个线程中释放。可以将acquire操作视为是消费一个许可,而release操作是创建一个许可,Semaphore并不受限于它在创建时的初始许可数量。

按照笔记中的描述,其实就是在限制连接的数量,如果连接超过10K,那么就会阻塞直到有别的连接断开后释放了信号量。这是控制IO流量的一种常见的方式。

构造方法

public SuspendResumeLock()
{
  this(true);
}

private SuspendResumeLock(final boolean createSemaphore)
{
  acquisitionSemaphore = (createSemaphore ? new Semaphore(MAX_PERMITS, true) : null);
}

默认构造器是带锁的,信号量的值为10K

Semaphore方法

  • public void acquire()
public void acquire() throws SQLException
{
  if (acquisitionSemaphore.tryAcquire()) {
     return;
  }
  else if (Boolean.getBoolean("com.zaxxer.hikari.throwIfSuspended")) {
     throw new SQLTransientException("The pool is currently suspended and configured to throw exceptions upon acquisition");
  }

  acquisitionSemaphore.acquireUninterruptibly();
}

获取信号量方法,首先会尝试获取信号量,如果没有获取到并且配置文件配置了获取不到抛出异常,那么就会抛出sql异常。如果没有配置,那么就调用acquireUninterruptibly()方法继续等待获取信号量

  • public void release()
public void release()
{
  acquisitionSemaphore.release();
}

释放线程持有的信号量

  • public void suspend()
public void suspend()
{
  acquisitionSemaphore.acquireUninterruptibly(MAX_PERMITS);
}

获取所有信号量导致暂停

  • public void resume()
public void resume()
{
  acquisitionSemaphore.release(MAX_PERMITS);
}

释放所有信号量恢复连接池

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值