java database connection pool to facilitate their own learning _

1, using the wait / notification connector taken to implement timeouts

Package cn.enjoyedu.ch1.pool; 

Import the java.sql.Connection;
 Import java.util.LinkedList; 

** / 
 * Class Description: implement connection pool 
 * / 
public  class the DBPool { 

    / * a container for storing connection * / 
    Private  static the LinkedList <connection> the pool = new new the LinkedList <connection> (); 

    / * limits connection pool size * / 
    public the DBPool ( int initialSize) {
         IF (initialSize> 0 ) {
             for ( int I = 0; I <initialSize; ++ I ) {
                 // analog connections take
                pool.addLast (SqlConnectImpl.fetchConnection ()); 
            } 
        } 
    } 

    / * release the connection, notifies the other thread wait for a connection * / 
    public  void the releaseConnection (Connection Connection) {
         IF (Connection =! null ) {
             the synchronized (the pool) { 
                the pool .addLast (connection); 
                // notify other threads wait for a connection 
                pool.notifyAll (); 
            } 
        } 
    } 

    / * Get * / 
    // can not be acquired in connection mills, lS will return null 
    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); 
                    / * wake-up time, duration is recalculated wait * / 
                    Remaining = future- System.currentTimeMillis (); 
                } 
                Connection Connection = null ;
                 IF (! pool.isEmpty ()) { 
                    Connection = pool.removeFirst ( ); 
                } 
                return Connection; 
            } 
        } 

    } 
}
            

test

Package com.pool; 

Import the java.sql.Connection;
 Import java.util.concurrent.CountDownLatch;
 Import java.util.concurrent.atomic.AtomicInteger; 

/ ** 
 * Class Description: Test 1000 from the pool to take concurrent connections 
 * / 
public  class DBPoolTest {
     static DBPool the pool = new new DBPool (10 );
     // controller: control main thread will wait for the end of all Woker before proceeding to the 
    static CountDownLatch end; 

    public  static  void main (String [] args) throws Exception {
         // The number of threads 
        int threadCount = 50 ; 
        End= New new a CountDownLatch (threadCount);
         int COUNT = 20 is; // number of operations of each thread 
        of AtomicInteger GOT = new new of AtomicInteger (); // counter: Statistics can get connected to the thread 
        of AtomicInteger notGot = new new of AtomicInteger (); // counter : statistics not get thread connection 
        for ( int I = 0; I <threadCount; I ++ ) { 
            the thread thread = new new the thread ( new new the worker (COUNT, gOT, notGot), 
                     "worker _" + I); 
            Thread.start () ; 
        } 
        end.await (); //main thread here waiting 
        System.out.println ( "Total tried:" + (threadCount * COUNT)); 
        System.out.println ( "get the number of connections:" + GOT); 
        System.out.println ( "number of failed connections:" + notGot); 
    } 

    static  class the Worker the implements the Runnable {
         int            COUNT; 
        of AtomicInteger GOT; 
        of AtomicInteger notGot; 

        public the Worker ( int COUNT, of AtomicInteger GOT, 
                               of AtomicInteger notGot) { 
            the this .count = COUNT;
             the this .got = GOT;
            the this .notGot = notGot; 
        } 

        public  void RUN () {
             the while (COUNT> 0 ) {
                 the try {
                     // obtain a connection from the thread pool, you can not take into 1000ms, will return null
                     // respectively counting the number of connections to obtain and got the number is not acquired notGot 
                    Connection Connection = pool.fetchConnection (1000 );
                     IF (Connection =! null ) {
                         the try { 
                            Connection.createStatement (); 
                            Connection.commit (); 
                        }finally {
                            pool.releaseConnection(connection);
                            got.incrementAndGet();
                        }
                    } else {
                        notGot.incrementAndGet();
                        System.out.println(Thread.currentThread().getName()
                                +"等待超时!");
                    }
                } catch (Exception ex) {
                } finally {
                    count--;
                }
            }
            end.countDown();
        }
    }
}

result

2, implemented using a database connection pool semaphores

Package com.semaphore; 

Import the java.sql.Connection;
 Import java.util.LinkedList;
 Import java.util.concurrent.Semaphore; 

/ ** 
 * Class Description: Semaphore implement database connection pool 
 * / 
public  class DBPoolSemaphore { 
    
    Private  Final  static  int = 10 pool_size ;
     // two indicators, respectively, as well as the available pool and are connected to connection 
    Private  Final Semaphore Useful, Useless;
     // storage container database connection 
    Private  static the LinkedList <connection> the pool = new new the LinkedList <connection> ( );
     // initialize the pool 
    static {
        for (int i = 0; i < POOL_SIZE; i++) {
            pool.addLast(SqlConnectImpl.fetchConnection());
        }
    }
    public DBPoolSemaphore() {
        this.useful = new Semaphore(10);
        this.useless = new Semaphore(0);
    }
    
    /*归还连接*/
    public void returnConnect(Connection connection) throws InterruptedException {
        if(connection!=null) {
            System.out.println("Currently" + useful.getQueueLength () + "threads waiting for database connections !!" 
                    + "number of available connections:" + useful.availablePermits ()); 
            useless.acquire (); 
            the synchronized (the pool) { 
                pool.addLast ( connection); 
            } 
            useful.release (); 
        } 
    } 
    
    / * from the pool to get connected to * / 
    public connection takeConnect () throws InterruptedException { 
        useful.acquire (); 
        connection connection; 
        the synchronized (the pool) { 
            connection = pool.removeFirst (); 
        } 
        useless.release (); 
        return connection;
    }
    
}

test

Package com.semaphore; 

Import the java.sql.Connection;
 Import java.util.Random; 

/ ** 
 * Class Description: Test database connection pool 
 * / 
public  class the AppTest { 

    Private  static DBPoolSemaphore DBPool = new new DBPoolSemaphore (); 
    
    Private  static  class BusiThread the extends the thread { 
        @Override 
        public  void RUN () { 
            the Random R & lt = new new the Random (); // make each thread holding time is not the same connection 
            Long Start = System.currentTimeMillis ();
             the try{ 
                Connection Connect = dbPool.takeConnect (); 
                System.out.println ( "the Thread _" + . Thread.currentThread () getId ()
                         + "_ [Total time database connection" + (System.currentTimeMillis () - start ) + "] MS." ); 
                SleepTools.ms ( 100 + r.nextInt (100)); // simulate business operations, thread holds the query data connection 
                System.out.println ( "query data is complete, return connection!" ) ; 
                dbPool.returnConnect (Connect); 
            } the catch (InterruptedException E) { 
            } 
        } 
    } 
    
    public  static  void main (String [] args) {
        for (int i = 0; i < 50; i++) {
            Thread thread = new BusiThread();
            thread.start();
        }
    }
    
}

result

 

package com.semaphore;

import java.sql.Connection;
import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.Semaphore;

/**
 *类说明:Semaphore实现数据库连接池
 */
public class DBPoolNoUseless {

    private final static int POOL_SIZE = 10;
    private final Semaphore useful;
    //存放数据库连接的容器
    private static LinkedList<Connection> pool = new LinkedList<Connection>();
    //初始化池
    static {
        for (int i = 0; i < POOL_SIZE; i++) {
            pool.addLast(SqlConnectImpl.fetchConnection());
        }
    }
    public DBPoolNoUseless() {
        this.useful = new Semaphore(10);
    }
    
    /*归还连接*/
    public void returnConnect(Connection connection) throws InterruptedException {
        if(connection!=null) {
            System.out.println("当前有"+useful.getQueueLength()+"个线程等待数据库连接!!"
                    +"可用连接数:"+useful.availablePermits());
            synchronized (pool) {
                pool.addLast(connection);
            }
            useful.release();
        }
    }
    
    /*从池子拿连接*/
    public Connection takeConnect() throws InterruptedException {
        useful.acquire();
        Connection connection;
        synchronized (pool) {
            connection = pool.removeFirst();
        }
        return connection;
    }

    private static DBPoolNoUseless dbPoolNoUseless = new DBPoolNoUseless();

    private static class BusiThread extends Thread{
        @Override
        public void run() {
            Random r = new Random();//让每个线程持有连接的时间不一样
            long start = System.currentTimeMillis();
            try {
                System.out.println("Thread_"+Thread.currentThread().getId()
                        +"_获取数据库连接共耗时【"+(System.currentTimeMillis()-start)+"】ms.");
                SleepTools.ms(100+r.nextInt(100));//模拟业务操作,线程持有连接查询数据
                System.out.println("查询数据完成,归还连接!");
                dbPoolNoUseless.returnConnect(new SqlConnectImpl());
            } catch (InterruptedException e) {
            }
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 50; i++) {
            Thread thread = new BusiThread();
            thread.start();
        }
    }
    
}

 

 

 

package cn.enjoyedu.ch1.pool;

import cn.enjoyedu.tools.SleepTools;

import java.sql.*;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;

/**
 *类说明:
 */
public class SqlConnectImpl implements Connection{
    
    /*拿一个数据库连接*/
    public static final Connection fetchConnection(){
        return new SqlConnectImpl();
    }

    //忽略其它    
}

 

Guess you like

Origin www.cnblogs.com/hongzm/p/11267313.html