封图| CSDN 下载于视觉中国
实现方式1:
很容易马上想到的一种方案,我们用一个map存放连接对象,需要的时候从map里拿来用就可以了。
我们来捋一捋这个实现会不会有并发的问题。假设两个线程同时进入else分支,在代码的28行可以确保只有一个线程会执行,也就是只会加入一个task。其它的线程都不会加入成功。
所以只有一个线程,这个线程开始异步执行创建连接的任务,而其它的线程则会调用的get方法直接获取结果。
实现方式3:
1和2的实现方式还存在一个问题, 多个线程获取到的其实同一个连接。这种方案在某些场景下是不允许的。比如spring数据库的事务管理器对于每个事务的处理线程都要求独立的连接资源。
下面的方案基于链表结构,有比较完整的获取,释放的操作,不同的线程可以拿到独立的连接资源。
druid连接池的实现原理
了解了实现连接池的大概思路,我们可以来继续学习下市面上比较成熟的连接池产品。这其中阿里巴巴开源的druid开源连接池就是一个代表。
先来看看在代码中如何使用Druid连接池,
方法主要的功能是根据配置文件初始化连接池,它内部会生成一些真正的物理连接然后放入一个数组里。当然这个方法要保证只会被调用一次。
继续往下看,最终会调用到这个私有方法,
代码逻辑也比较清楚,poolCount是连接池的目前的可用连接数量。
如果为0,就通过唤醒生产者线程创建新的连接,同时当前线程挂起等待的信 。维护的就是正在等待的消费者数量。
如果不为0,就从数组中取出最后一个连接返回。有人可能会有疑问,这里返回的是,不是啊/p>
其实看下前者的定义你就明白了,

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!