数据库连接池示例以及性能分析

来源:互联网 发布:淘宝html源代码 编辑:程序博客网 时间:2024/06/04 23:27

直接上代码:

连接池ConnectionPool:

package com.shuaicenglou.ConnectionPool;import java.util.LinkedList;public class ConnectionPool {private LinkedList<Connection> pool = new LinkedList<>();public ConnectionPool(int ininum){if(ininum>0){for(int i=0;i<ininum;i++) pool.addLast(new Connection(Integer.toString(i+1)));}}public void relese(Connection connection){if(connection!=null){synchronized (pool) {pool.addLast(connection);pool.notifyAll();}}}public Connection getConnection(long millis){synchronized (pool) {if(!pool.isEmpty()){return pool.removeLast();}else{long future = System.currentTimeMillis()+millis;long remaning = millis;while(pool.isEmpty()&&remaning>0){try {pool.wait(remaning);remaning = future - System.currentTimeMillis();} catch (InterruptedException e) {e.printStackTrace();}}Connection result = null;if(!pool.isEmpty()) result = pool.removeLast();return result;}}}}
在超时等待那里,也就是代码的27-34行,我原本是直接使用pool.wait(remaning);没有像<<Java并发编程的艺术>>上面那样使用future-remaining的写法,这导致我的连接池超时等待时间莫名地比书上的短,此处为何使用future-remaining的写法会让连接等待时间长一些,我无法理解,但是我的实现与<<Java并发编程的艺术>>上的实现对比,我的实现在并发程度高的时候劣化不够平缓。

模拟的数据库Connection:其commit方法只是睡眠100毫秒:

package com.shuaicenglou.ConnectionPool;import java.util.concurrent.TimeUnit;import java.util.jar.Attributes.Name;public class Connection {private String name;public Connection(String name){this.name = name;}public void commit(){try {TimeUnit.MILLISECONDS.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}

测试:
package com.shuaicenglou.ConnectionPool;import java.util.concurrent.CountDownLatch;import java.util.concurrent.atomic.AtomicInteger;public class Test {static ConnectionPool pool = new ConnectionPool(10);static CountDownLatch start = new CountDownLatch(1);static CountDownLatch end;public static void main(String[] args)throws Exception {int threadCount = 20;end = new CountDownLatch(threadCount);int count = 20;AtomicInteger got = new AtomicInteger();AtomicInteger notGot = new AtomicInteger();for(int i=0;i<threadCount;i++){Thread thread = new Thread(new R(count, got, notGot),"ConnectionRunnerThread");thread.start();}start.countDown();end.await();System.out.println("total invoke:"+(threadCount * count));System.out.println("got connection:"+got);System.out.println("not got:"+notGot);}static class R implements Runnable{int count;AtomicInteger got,notGot;public R(int count,AtomicInteger got,AtomicInteger notGot) {this.count = count;this.got = got;this.notGot = notGot;}@Overridepublic void run() {try {start.await();} catch (InterruptedException e) {e.printStackTrace();}for(int i=0;i<count;i++){Connection c = pool.getConnection(1000);if(c!=null){c.commit();got.incrementAndGet();pool.relese(c);}else notGot.incrementAndGet();}end.countDown();}}}
结果: