接続を作成するため、ConnectionDriverをシミュレート
パッケージtread.demo.threadpool。 輸入java.lang.reflect.InvocationHandler。 輸入java.lang.reflect.Methodオブジェクト。 輸入java.lang.reflect.Proxyの; インポートのjava.sql.Connection; 輸入java.util.concurrent.TimeUnit。 パブリック クラスConnectionDriver { 静的 クラス ConnectionHandlerは実装のInvocationHandler { パブリックオブジェクトを呼び出し(オブジェクトプロキシ、方法方法、[]引数オブジェクト)がスローのThrowable { 戻り ヌル。 } } パブリック 静的 最終接続のcreateConnection(){ リターン(接続)たとえば、Proxy.newProxyInstance(ConnectionDriver。クラス .getClassLoader()、新しいクラス[] {接続<?>。クラス }、新しいConnectionHandler())。 } }
スレッドプールの実装:
パッケージtread.demo.threadpool。 インポートのjava.sql.Connection; 輸入java.util.LinkedList; パブリック クラスのConnectionPool { プライベート LinkedListの<接続>プール= 新しい LinkedListの<接続> (); 公共のConnectionPool(INT INITIALSIZE){ 場合(INITIALSIZE> 0 ){ ため(int型、iはINITIALSIZEを<; I = 0 iは++ ){ pool.addLast(ConnectionDriver.createConnection())。 } } } パブリック 無効releaseConnection(コネクション接続){ 場合(接続!= NULL ){ 同期(プール){ pool.addLast(接続)。// 将接続还回给プール pool.notifyAll(); // 通知等待的线程 } } } パブリック接続fetchConnection(ロングミル)をスロー例外{ 同期{(プール) であれば(ミル<= 0 ){ 一方(pool.isEmpty()){ pool.wait()。//バンドはされている他のリリース- 「通知 } を返す pool.removeFirstを(); // 接続を取得 } 他{ ロングフューチャー=にSystem.currentTimeMillis()+ ミルズ、 ロング =残り;ミルズ しばらく(pool.isEmpty()を&&> 0を残りの){ // タイムアウトするまでの待機時間に基づいて。 pool.wait(); 残り =未来- のSystem.currentTimeMillis(); } 接続結果 = NULL ; IF(!pool.isEmpty()){ 結果 = pool.removeFirst()。 } 戻り値の結果; } } } }
2:
- オブジェクト待つと通知
- タイムアウトは、時間ベースのを待っています。
テスト:
パッケージtread.demo.threadpool。 インポートのjava.sql.Connection; 輸入java.util.concurrent.CountDownLatch。 輸入java.util.concurrent.atomic.AtomicInteger。 パブリック クラスConnectionPoolTest { 静的のConnectionPoolプール= 新規のConnectionPool(10 )。 静的たCountDownLatch開始= 新しいたCountDownLatch(1 )。 静的たCountDownLatchの終わり; パブリック 静的 ボイドメイン(文字列[]引数)スロー例外{ int型スレッドカウント= 1000 。 終わり= 新しいたCountDownLatch(THREADCOUNT)。 int型のカウント数= 20 ; AtomicIntegerは持っ = 新しい)(のAtomicIntegerを。 AtomicInteger notGot = 新しいのAtomicInteger(); 以下のために(int型 ;私は<THREADCOUNT; I = 0私は++ ){ スレッドスレッド = 新しいスレッド(新しい ConnectionRunnerは(カウント、notGot)だ、 "ConnectionRunnerThread" ); thread.start(); } start.countDown()。// タルト的カウントダウン为0、保证了所有线程同时执行。 end.await();// 等待所有线程执行完毕、 するSystem.out.println( "総呼び出し:" +(THREADCOUNTの*の数)); System.out.println( "接続を得た:" +を得ました)。 System.out.println( "ではない持っ接続:" + notGot)。 } 静的 クラス ConnectionRunnerは実装のRunnable { intは数えます。 AtomicIntegerを得ました。 AtomicInteger notGot; 公共 ConnectionRunner(int型の数、のAtomicIntegerが得た、のAtomicInteger notGot){ この .count = 数えます。 この .gotを=なりました。 この .notGot = notGot。 } 公共 ボイドラン(){ しようと{ )(start.awaitを。//は的のカウントダウン为0を開始し等待。 } キャッチ(InterruptedExceptionある電子){ e.printStackTrace(); } ながら(カウント> 0 ){ 試みる{ 接続の接続 = pool.fetchConnection(1)。// 超时时间 場合(接続!= nullの){ しようと{ connection.createStatement(); } 最後に{ pool.releaseConnection(接続)。 got.incrementAndGet(); } } 他{ notGot.incrementAndGet()。 } } キャッチ(例外例){ } 最後に{ カウント - 。 } } end.countDown()。 } } }
CatdownLatchを継続して使用します
結果:
合計呼び出し:20000は 、接続を得た: 11914 持っていない接続: 8086を
あなたはタイムアウトを調整した場合は、100ミリ秒に調整
結果は次の通りである(ほとんどの時間は、接続を取得することができます)
合計呼び出し:20000は 、接続を得た: 19050 持っていない接続: 950