簡單的資料庫連接池執行個體(java語言)

來源:互聯網
上載者:User

標籤:感知   lex   --   load   exce   逾時   handler   etc   stack   

1.概述

頻繁的建立和銷毀資料庫連接消耗非常多的系統資源,建立一個池子, 管理一定數量的串連,用的時候去池中取,用完了放回池中,這時比較通用的做法。

 

2.關鍵字

LinkedList  synchronized  InvocationHandler  CountDownLatch

 

3. 代碼

3.1 ConnectionPool.java

package com.rocky.pool;import java.sql.Connection;import java.util.LinkedList;public class ConnectionPool {    private LinkedList<Connection> pool = new LinkedList<Connection>();        public ConnectionPool(int initialSize){        if(initialSize > 0){            for(int i=0; i<initialSize; i++){                pool.addLast(ConnectionDriver.createConection());            }        }    }        public void releaseConnection(Connection connection){        if(connection != null){            synchronized (pool) {                //串連釋放後 要進行通知 這樣其他消費者能夠感知池中已經歸還了一個串連                pool.addLast(connection);//                pool.notifyAll();//all                pool.notify();//all                            }        }    }        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;            }        }            }}

3.2 ConnectionDriver.java

package com.rocky.pool;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.sql.Connection;public class ConnectionDriver {    static class ConnectionHandler implements InvocationHandler{        @Override        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {            if(method.getName().equals("commit")){                Thread.sleep(1000);            }            return null;        }    }        //建立一個connection的代理    public static Connection createConection(){        return (Connection) Proxy.newProxyInstance(ConnectionDriver.class.getClassLoader(), new Class<?>[]{Connection.class},new ConnectionHandler());    } }

3.3 ConnectionPoolTest.java

package com.rocky.pool;import java.sql.Connection;import java.sql.SQLException;import java.util.concurrent.CountDownLatch;import java.util.concurrent.atomic.AtomicInteger;public class ConnectionPoolTest {    static ConnectionPool pool = new ConnectionPool(10);        //保證所有runner能夠同時運行    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 ConnectionRunner(count, got, notGot), "ConectionRunnerThread"+i);            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);    }        static class ConnectionRunner implements Runnable{        int count ;        AtomicInteger got;        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(count > 0){                try {                    Connection connection = pool.fetchConnection(1000);                    if(connection != null){                        try{                            connection.createStatement();                            connection.commit();                        }finally{                            pool.releaseConnection(connection);                            got.incrementAndGet();                        }                    }else{                        notGot.incrementAndGet();                    }                } catch (InterruptedException | SQLException e) {                    e.printStackTrace();                }finally{                    count--;                }            }            end.countDown();        }            }    }

3.4 說明

通過改變main方法中的threadCount的數量可以觀察 隨著線程數的增加 擷取串連命中的比例在下降,

這時因為串連池中的串連數一定(10個) 而用戶端線程會等待並逾時返回。

 

簡單的資料庫連接池執行個體(java語言)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.