• 连接池


    什么是连接池呢?

      我们登陆上某个网站,去修改个人信息、点击下单、修改购买商品的数量......当我们做这些操作时候,

    我们已经连接上数据库并修改、增加、删除数据库中的数据,完成操作后,关闭连接(避免占用资源)。

    如果很多人访问这个网站并进行操作,那要创建很多个连接,而且只操作一次就关闭,这会显著的影响系统的

    性能。连接池  就为解决这个难题应运而生。

    连接池: 

      在系统初始化的时候,将数据库连接作为对象存放在内存中。当用户要访问数据库时,取出一个连接,

    完成操作后归还到池中,等待下个用户使用。连接的创建、断开都由池来管理。我们可以设置连接池的参

    数控制初始连接数、连接的上下限数、最大空闲时间......这项技术明显的提高对数据库操作的性能。

    线程池:

    package org3.pool;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.sql.Connection;
    import java.util.concurrent.LinkedBlockingQueue;
    
    /**
     * Created by Administrator on 2016/11/25.
     * 编写一个线程池
     */
    public class Pool {
    
    
        private int minSize = 1;    //定义最小连接数,默认为2
        private int maxSize = 2;    //定义最大连接数,默认为4
        private int fetchCount = minSize;   //记录从数据库抓取的连接数
        private LinkedBlockingQueue<Connection> pool;   //定义一个阻塞队列,充当连接池
    
        public void setMinSize(int minSize) {
            this.minSize = minSize;
            this.fetchCount = minSize;
        }
    
        public void setMaxSize(int maxSize) {
            this.maxSize = maxSize;
        }
    
        //初始化线程池方法
        public void initPool() {
            //初始化连接池的最大值
            pool = new LinkedBlockingQueue<>( maxSize );
            //预先存放minSize个连接
            for ( int i = 0 ; i < minSize ; i++ ) {
                pool.add( DBUtil.getConnection() );
            }
        }
    
        //从数据库抓取连接方法
        public synchronized Connection getConnection() {
            //检查连接池状况,如果检查未通过将直接引发异常,程序终止
            checkFetch();
            Connection conn = null;
            try {
                conn = getProxyConnection();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return conn;
        }
    
        //检查连接池的状况
        private void checkFetch() {
            //当连接池大小为0 且 连接记录数还没达到最大值时
            if ( pool.isEmpty() && fetchCount < maxSize ) {
                pool.add( DBUtil.getConnection() );
            }
        }
    
        //从连接池获取连接,并将获取的连接创建一个代理对象
        private Connection getProxyConnection() throws InterruptedException {
            //先从池中获取未代理的连接对象
            Connection conn = pool.take();
            //将获取的链接创建代理对象
            return createProxy( conn );
        }
    
        //使用内部类来实现InvocationHandler
        private Connection createProxy( Connection conn ) {
            return ( Connection )Proxy.newProxyInstance( Connection.class.getClass().getClassLoader(), new Class[] { Connection.class }, new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    //如果客户端调用的是close方法,就将连接放回连接池
                    if( "close".equals(method.getName() ) ) {
                        pool.put( conn );
                        fetchCount--;
                    }
                    //如果是Connection其他的方法,将正常回调,也就是放行
                    return method.invoke(conn,args);
                }
            });
        }
    
        //查看连接池当前连接数
        public int size() {
            return pool.size();
        }
    }
    

    DBUtil:

    package org3.pool;
    
    import java.sql.*;
    
    /**
     * Created by Administrator on 2016/11/25.
     */
    public class DBUtil {
    
        private static String driver = "oracle.jdbc.driver.OracleDriver";   //数据库驱动
        private static String url = "jdbc:oracle:thin:@localhost:1521:orcl";    //数据库的资源地址
        private static String userName = "mark";    //用户名
        private static String password = "mark";    //密码
    
        static {
            try {
                Class.forName( driver );
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    
        public static Connection getConnection() {
            Connection conn = null;
            try {
                conn = DriverManager.getConnection( url, userName, password );
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return conn;
        }
    
    
        //main方法(用于测试)
        public static void main(String[] args) {
            System.out.println( getConnection() );
        }
    }
    

    编写一个线程:

    package org3.pool;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    
    /**
     * Created by Administrator on 2016/11/26.
     * 编写线程1
     */
    public class User1 extends Thread {
    
        //定义连接池对象
        private Pool pool;
    
        public User1( Pool pool ) {
            this.pool = pool;
        }
    
        //重写Thread的run方法
        @Override
        public void run() {
            Connection conn = pool.getConnection();
            System.out.println(Thread.currentThread().getName() + "获取了一个连接:" + conn);
            try {
                Thread.sleep( 500 );
                conn.close();
                System.out.println(Thread.currentThread().getName() + "归还了一个连接: " + conn);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    main方法:

    package org3.pool;
    
    import java.sql.SQLException;
    
    /**
     * Created by Administrator on 2016/11/25.
     * main方法
     */
    public class Main {
        public static void main(String[] args) throws SQLException {
            //实例化连接池对象
            Pool pool = new Pool();
            //给连接池设置属性
            pool.setMinSize( 2 );
            pool.setMaxSize( 5 );
            //初始化连接池
            pool.initPool();
    
            for( int i = 0; i < 10; i++ ){
                User1 u1 = new User1( pool );
                u1.start();
            }
    
            try {
                Thread.sleep( 10000 );
                System.out.println( "线程大小= " + pool.size() );
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    }
    

    运行结果:

    -------------------------------------------------------------------------

  • 相关阅读:
    ti processor sdk linux am335x evm setup.sh hacking
    ti processor sdk linux am335x evm Makefile hacking
    导出Excel数据
    使用dom4j解析XML例子
    java解析xml文件并输出
    java解析xml文件
    java解析XML获取城市代码
    drop.delete.trauncat的区别
    hibernate 中id生成策略
    如何使java中double类型不以科学计数法表示
  • 原文地址:https://www.cnblogs.com/hmake/p/6107280.html
Copyright © 2020-2023  润新知