多线程--数据库连接池与等待超时模式

public class ConnectionPool {

    /**
     * 空闲连接池
     */
    private LinkedList<Connection> pool = new LinkedList<Connection>();

    /**
     * 连接池初始化
     * @param initialSize
     */
    public ConnectionPool(int initialSize) {
        if (initialSize > 0) {
            for (int i = 0; i < initialSize; i++) {
                pool.addLast(ConnectionDriver.createConnection());
            }
        }
    }

    /**
     * 释放连接
     * @param connection
     */
    public void releaseConnection(Connection connection) {
        if (connection != null) {
            synchronized (pool) {
                pool.addLast(connection);
                //唤醒等待在该pool上的线程
                pool.notifyAll();
            }
        }
    }

    /**
     * 获取连接
     * 
     * @param mills
     * @return
     * @throws InterruptedException
     */
    public Connection fetchConnection(long mills) throws InterruptedException {
        synchronized (pool) {
            if (mills <= 0) {
                while (pool.isEmpty()) {
                    pool.wait();
                }
                return pool.removeFirst();
            } else {
                long future = System.currentTimeMillis() + mills;
                long remaining = mills;
                while (pool.isEmpty() && remaining > 0) {
                    pool.wait(remaining);
                    remaining = future - System.currentTimeMillis();
                }
                Connection result = null;
                if (!pool.isEmpty()) {
                    result = pool.removeFirst();
                }
                return result;
            }
        }
    }
}
public class ConnectionDriver {

    private static class ConnectionHandler implements InvocationHandler {

        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            if (method.getName().equals("commit")) {
                TimeUnit.MILLISECONDS.sleep(100);
            }
            return null;
        }
    }

    public static final Connection createConnection() {
        return (Connection) Proxy.newProxyInstance(
                ConnectionDriver.class.getClassLoader(),
                new Class<?>[] { Connection.class }, new ConnectionHandler());
    }
}

测试代码:

public class ConnectionPoolTest {

    private static ConnectionPool pool = new ConnectionPool(10);

    private static CountDownLatch start = new CountDownLatch(1);

    private static CountDownLatch end;

    public static void main(String[] args) throws InterruptedException {
        int threadCount =100;
        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 ConnectionRunner(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 connection " + notGot);
    }

    private static class ConnectionRunner implements Runnable {

        private int count;

        private AtomicInteger got;

        private AtomicInteger notGot;

        public ConnectionRunner(int count, AtomicInteger got,
                AtomicInteger notGot) {
            this.count = count;
            this.got = got;
            this.notGot = notGot;
        }

        @Override
        public void run() {
            try {
                start.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            while (this.count > 0) {
                try {
                    Connection connection = pool.fetchConnection(100);
                    if (connection != null) {
                        try {
                            connection.createStatement();
                            connection.commit();
                        } catch (SQLException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } finally {
                            pool.releaseConnection(connection);
                            got.incrementAndGet();
                        }
                    } else {
                        notGot.incrementAndGet();
                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } finally {
                    this.count--;
                }
            }
            end.countDown();
        }
    }
}

当在指定的时间内无法获取到连接时,将会返回为空,核心代码为fetchConnection.

摘自《Java并发编程的艺术》

猜你喜欢

转载自blog.csdn.net/BtWangZhi/article/details/82315743
今日推荐