静的メソッドのgetConnectionを(提供DriverManagerクラスでJDBC API設計は、)このメソッドは、接続インスタンスを返すために、データベースへの接続を確立するために使用されます。
新しいインターフェイスAPIのバージョンJDBC2.0提供:のjavax.sql.DataSourceを、このインタフェースはまたのgetConnection()抽象メソッドを提供し、ドルイドは、接続プールを達成するためのインターフェイスに基づいてすなわち:DruidDataSource実装クラスを作りました。
以下はDruidDataSourceのgetConnection()インターフェースを集中します、我々は最初のjavax.sql.DataSourceインタフェースを見つけることができます。
簡単にプロセス
DruidDataSource実装クラスをダウン検索
そして、のgetConnection()の実装
我々はのgetConnection()メソッドの内部に、上院(最大待機時間)にMAXWAITを渡し、内部メソッドを呼び出して見ます
2)接続を得ること;のgetConnection()メソッドは、主に二つのステップ、1)接続プールの初期化動作で行われます。
私たちは、initメソッドの初期に見て、初期化メソッドは、非常に長いです、ここでは2つのコンテンツを、次の
図1に示すように、同期の初期化に接続します
ここでは、第一MAXACTIVE基づくアレイ構成は、接続を作成し、INITIALSIZEに従って対応する配列に初期化され、記憶された接続インスタンスを構成参照します。(これは、スレッドプールは、接続プールを作成することで、同じとThreadPoolExecutorスレッドプールではありません最初のすべての直接作成されていない、フォローアップをinitメソッドを呼び出すことなくなりました)。
図2に示すように、糸の生産は、同期接続の初期化の場合にはプロデューサーとしてのねじ接続の作成を開始します。
私たちは、実装生産者スレッドのrunメソッド、主に以下の2つのコードをオープンしました
第一の部分は、作成された信号接続を待ちます
第二の部分、非ヌル信号生成の完了は、(作成されたスレッドは、消費者の接続への通知を待っています)
私たちは、初期化プロセスにおけるコネクション接続の対応する番号を作成、参照、その後、スレッドは接続の生産者が接続接続を作成するために、消費者に知らせる待機を開始することができます。
init方法结束以后,我们再进入getConnectionDirect方法看看怎么获取连接
该方法又调用了一个内部方法,如果失败有重试机制,再进入内部方法
getConnectionInternal方法很长,我们忽略次要部分,关注以下内容
如果设置了等待时间则调用pollLast阻塞等待,如果没有则调用takeLast无限阻塞。这里我们点开pollLast()方法看看
首先,如果没有Connection就会发送空的信号给我们上面的生产者线程
然后就阻塞等待生产者的通知
等待结束以后再次判断是否为空(这里是典型的条件谓词的二次校验做法),还为空则再循环一遍。
如果有可用连接将获取并返回
原理实现
DruidDataSource的原理看起来比较简单,就是基于ReentrantLock和Condition的条件队列实现了生产者和消费者模式。生产者由一个线程处理(同步模式),消费者多线程。
下面我们看一个伪代码:
首先定义一把锁和两个信号,一个是空信号,一个是非空信号
生产者,先进行条件判断,如果非空则进入等待,如果空,则创建
消费者
伪代码中注意一点,wait方法在之前要做条件谓词判断,之后也要做条件谓词判断这样才不会导致信号丢失。