实现连接池功能

在这里插入图片描述
获取连接

package com.example.demo.conf;


import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
//"classpath:config/config.properties"
@PropertySource({"classpath:jdbc.properties"})
@Component
public class MyJdbcConnect {

    //@Value("${spring.datasource.driver-class-name}")
    private static String drivter ;
   // @Value("${spring.datasource.url}")
    private static String url ;
   // @Value("${spring.datasource.username}")
    private static String username ;
   // @Value("${spring.datasource.password}")
    private static String password;
    private  Connection connection;
    static {
      try {
            Class.forName(drivter);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }



    public MyJdbcConnect() {
      
        try {
            connection = DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public Connection getConnection(){
       return connection;
    }
    public void close(){
        try {
            if (connection != null && !connection.isClosed()){
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

连接池

package com.example.demo.conf;

import com.example.demo.database.MyDataSource;
import org.springframework.context.annotation.Configuration;

import java.io.InputStream;
import java.sql.Driver;
import java.sql.DriverManager;
import java.util.Properties;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@Configuration
public class MyPool {
    //源代码中的所有参数属性都是对外的配置
    private static String driver = null;
    private static String url = null;
    private static String user = null;
    private static String password = null;

    //限制连接池中的管道数量参数
    private static int initCount = 4;
    private static int stepSize = 10;
    private static int poolMaxSize = 150;




    private   int maxActive=20;
    private  long maxWait=10000L;
    private int maxIdle=10;

        // 数据库连接池里的Jdbc连接有2种状态,一是正在使用中,二是用过以后又被返还的空闲中
        LinkedBlockingQueue<MyJdbcConnect> busy;
        LinkedBlockingQueue<MyJdbcConnect> idle;

        // 目前在池子中已创建的连接数(不能大于最大连接数maxActive)
        AtomicInteger createdCount = new AtomicInteger(0);

        /**
         * 连接池初始化
         *
         * @param maxActive 最大连接数量,连接数连不能超过该值
         * @param maxWait   超时等待时间以毫秒为单位 6000毫秒/1000等于60秒,当连接超过该时间便认为其实空闲连接
         * @param maxIdle   最大空闲连接,当空闲连接超过该值时就挨个关闭多余的连接,但不能小于minldle
         */
        public void init(int maxActive, long maxWait, int maxIdle) {
            this.maxActive = maxActive;
            this.maxWait = maxWait;
            this.maxIdle = maxIdle;
            this.busy = new LinkedBlockingQueue<>();
            this.idle = new LinkedBlockingQueue<>();
        }

       public MyPool() {
        init(maxActive,maxWait,maxIdle);
    }

    /**
         * 从连接池中获取数据库连接。忽略poll、offer的结果判断。
         */
        public MyJdbcConnect getResource() throws Exception {
            MyJdbcConnect myJdbcConnect = null;
                myJdbcConnect = idle.poll();

            // 有空闲的可以用
            if (myJdbcConnect != null) {
                boolean offerResult = busy.offer(myJdbcConnect);
                return myJdbcConnect;
            }
            // 没有空闲的,看当前已建立的连接数是否已达最大连接数maxActive
            if (createdCount.get() < maxActive) {
                // 已建立9个,maxActive=10。3个线程同时进来..
                if (createdCount.incrementAndGet() <= maxActive) {
                    myJdbcConnect = new MyJdbcConnect();
                    boolean offerResult = busy.offer(myJdbcConnect);
                    return myJdbcConnect;
                } else {
                    createdCount.decrementAndGet();
                }
            }
            // 达到了最大连接数,需等待释放连接
            myJdbcConnect = idle.poll(maxWait, TimeUnit.MILLISECONDS);
            if (myJdbcConnect != null) {
                boolean offerResult = busy.offer(myJdbcConnect);
                return myJdbcConnect;
            } else {
                throw new Exception("等待超时!");
            }
        }

        /**
         * 将数据库连接返还给连接池。忽略poll、offer的结果判断。
         */
        public void returnResource(MyJdbcConnect jdbcConnect) {
            if (jdbcConnect == null) {
                return;
            }
            // 忽略连接状态的检查
            // jdbcConnect.getConnection().isClosed()
            boolean removeResult = busy.remove(jdbcConnect);
            if (removeResult) {
                // 控制空闲连接的数量
                if (maxIdle <= idle.size()) {
                    jdbcConnect.close();
                    createdCount.decrementAndGet();
                    return;
                }
                boolean offerResult = idle.offer(jdbcConnect);
                if (!offerResult) {
                    jdbcConnect.close();
                    createdCount.decrementAndGet();
                }
            } else {
                // 无法复用
                jdbcConnect.close();
                createdCount.decrementAndGet();
            }
        }
    }


测试

package com.example.demo.conf;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.CountDownLatch;

public class Test {

    final static int threadNums = 100;
   private final static CountDownLatch COUNT_DOWN_LATCH = new CountDownLatch(threadNums);
    public static void main(String[] args) {
//        MyJdbcConnect myJdbcConnect = new MyJdbcConnect();
//        Connection connection = myJdbcConnect.getConnection();

         MyPool myPool = new MyPool();

        for (int i = 0; i < threadNums; i++) {

            new Thread(new Runnable() {
                @Override
                public void run() {
                    MyJdbcConnect resource=null;
                    try {
                        COUNT_DOWN_LATCH.await();
                        String sql = "select * from user";


                      resource = myPool.getResource();
                        Connection connection = resource.getConnection();

                        Statement statement = connection.createStatement();
                        ResultSet resultSet = statement.executeQuery(sql);

                        resultSet.next();
                        System.out.println(
                                Thread.currentThread().getName()+"查询结果"+resultSet.getString("userEname")
                        );

                    } catch (Exception e) {
                        e.printStackTrace();
                    }finally {
                        myPool.returnResource(resource);
                    }
                }
            }).start();
            COUNT_DOWN_LATCH.countDown();
        }

    }
}

配置文件获取参数


import java.io.InputStream;
import java.util.Properties;



public class ProperUtil {
    private static String driver = null;
    private static String url = null;
    private static String user = null;
    private static String password = null;

    //限制连接池中的管道数量参数
    private static int initCount = 4;
    private static int stepSize = 10;
    private static int poolMaxSize = 150;

    public void getFile(){
        InputStream input = this.getClass().getClassLoader().getResourceAsStream("jdbc.properties");
        Properties properties = new Properties();
        try {
            properties.load(input);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //解析数据
        driver = properties.getProperty("jdbc.driverClassName");
        url = properties.getProperty("jdbc.url");
        user = properties.getProperty("jdbc.username");
        password = properties.getProperty("jdbc.password");
        //对字节信息进行判断
        if (Integer.valueOf(properties.getProperty("jdbc.initialSize")) > 0) {
            initCount = Integer.valueOf(properties.getProperty("jdbc.initialSize"));
        }
        if (Integer.valueOf(properties.getProperty("jdbc.maxActive")) > 0) {
            poolMaxSize = Integer.valueOf(properties.getProperty("jdbc.maxActive"));
        }
        if (Integer.valueOf(properties.getProperty("jdbc.stepSize")) > 0) {
            stepSize = Integer.valueOf(properties.getProperty("jdbc.stepSize"));
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值