HikariCP流程,一图概括了解(源码入门)

【思考】

1、连接池作用:估计都知道,保存数据库连接,避免下次请求时再新建耗时。
2、连接池存什么? 平常可能不太注意,仔细翻翻源码稍微思考一下就知道了。Mysql连接是mysql-connector-java.jar提供的,他给我返回Connection实例。而连接池存的就是Connection实例,高效的提供给多线程使用。
3、那到底跟我们自己List存一下有什么区别呢?也就是连接池解决什么问题、如何高效:多线程时,每个线程使用一个Connection,可能有100个线程同时getConnection,我们只有10个,那就需要让有的线程等待。这就是要解决的并发问题。至于如何高效,emmm…HikariCP优化了很多细节,这里不研究。我今天只说说它的主要流程,也是自己看过后的总结,希望帮助大家入门。


【主要类】

1、HikariDataSource:就是一个DataSource,包含HikariPoo成员变量
2、HikariPool:HikariCP的入口,包含了ConcurrentBag成员变量
3、ConcurrentBag:用于高效处理并发的类,包含了ThreadLocal<List<T>> threadList、CopyOnWriteArrayList<T> sharedList、SynchronousQueue<T> handoffQueue。这三个变量就是核心,他们是储存Connection的地方。
4、PoolEntry:封装储存Connection的类,可以理解一个PoolEntry就是一个Connection。


【如何管理的】
哈哈,其实我就是想说说ConcurrentBag里面的那三个变量,可以从这三个地方获取到Connection。

ThreadLocal<List> threadList 可以称之为“第一选择”。
一个线程获取到Connection用完后,先存在ThreadLocal,下次就可以直接先用了,如果去sharedList里拿,还要对waiter这个AotmicInteger进行CAS操作,直接拿更快。

CopyOnWriteArrayList sharedList 可以称之为“第二选择”。
所有创建的Connection都储存在这个list中。

SynchronousQueue handoffQueue 可以称之为“最后的选择”。
如果以上两个地方都拿不到PoolEntry,那就来这个队列等着。等到天荒地老,直到timeout超时。


【流程图讲解】
1、不管哪个线程池,获取Connection接口都是DataSource.getConnection()
2、之后会调用到HikariCP的核心ConcurrentBag.borrow方法。开始了它的选择之路,也就是我说的三种选择。
3、第一选择:ThreadLoacl。第一次肯定是没有的,如果之前用过,那第二次就可以直接用。不过用之前要先看看PoolEntry的状态,因为,别的线程可能已经通过sharedList“偷”走了它。
4、第二选择:SharedList。遍历看看PoolEntry的状态,如果有未使用的,那就拿过来用。因为可能会偷了别家线程的,所以要给Listener发个消息,通知创建一个add任务新建Connection。
5、第三选择,最后的倔强:handoffQueue。如果现有的PoolEntry都不可用,那就要执行一次add任务了,跟上面的方法相同。通知完,就doWhile起来,在那等,add任务创建的PoolEntry或者其他方法归还的PoolEntry都会放到队列中。如果等不到,那timeout了就抛异常了。
6、归还。ProxyConnection.close()方法,补充一下ProxyConnection是对PoolEntry的包装。偶买噶。最终会调用bag的requite[翻译为“报答、归还”吧]方法。改方法有两个去向,当waiter>0时,就给队列,否则就放到ThreadLoacl里。


【后续】
太复杂了,如果还有后续的话。。。。


在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值