java多线程之-自定义数据库连接池


1.背景

数据库链接池大家不陌生吧...

不多说了,直上代码...

2.连接池具体实现

1.jdbc链接的实例对象

/**
 * @author 姿势帝-博客园
 * @address https://www.cnblogs.com/newAndHui/
 * @WeChat 851298348
 * @create 02/19 8:17
 * @description
 * 

* 模拟一个实现jdbc链接的实例 *

*/ @Data public class MyConnectionImpl implements Connection { private String name; // TODO 实现接口的方法 }

2.连接池对象

package com.ldp.demo09Pool;

import lombok.extern.slf4j.Slf4j;

import java.sql.Connection;
import java.util.concurrent.atomic.AtomicIntegerArray;

/**
 * @author 姿势帝-博客园
 * @address https://www.cnblogs.com/newAndHui/
 * @WeChat 851298348
 * @create 02/19 8:10
 * @description 

* 自定义一个数据库连接池 * 练习多线程,原子性等概念的理解 *

*/ @Slf4j public class MyDataPool { // 1.链接数 private int poolSize; // 2.链接对象数组 private Connection[] connectionArray; // 3.记录链接状态的数组,0-链接可用,1-链接不可用 private AtomicIntegerArray statusArray; /** * 构造方法 * * @param poolSize */ public MyDataPool(int poolSize) { this.poolSize = poolSize; this.connectionArray = new Connection[poolSize]; this.statusArray = new AtomicIntegerArray(new int[poolSize]); for (int i = 0; i < poolSize; i++) { connectionArray[i] = new MyConnectionImpl("连接对象-" + i); } } /** * 获取一个链接 * * @return */ public Connection getConnection() { while (true) { for (int i = 0; i < poolSize; i++) { if (statusArray.get(i) == 0) { // 0-链接可用,1-链接不可用 if (statusArray.compareAndSet(i, 0, 1)) { // 获取连接成功 return connectionArray[i]; } } } synchronized (this) { try { // 如果没获取到链接,等待,实际开发中这里可以设置一个等待时长 log.info("无可用链接等待中...."); this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } /** * 将连接放回连接池 * * @param connection */ public void closeConnection(Connection connection) { for (int i = 0; i < poolSize; i++) { if (connectionArray[i] == connection) { // 设置归返的链接可用 statusArray.set(i, 0); // 唤醒其他线程获取连接 synchronized (this) { this.notify(); } break; } } // 异常处理... } }

3.测试

package com.ldp.demo09Pool;

import com.common.MyThreadUtil;
import lombok.extern.slf4j.Slf4j;

import java.sql.Connection;
import java.util.Random;

/**
 * @author 姿势帝-博客园
 * @address https://www.cnblogs.com/newAndHui/
 * @WeChat 851298348
 * @create 02/19 8:42
 * @description
 */
@Slf4j
public class Test01 {
    /**
     * 测试连接池使用
     *
     * @param args
     */
    public static void main(String[] args) {
        MyDataPool dataPool = new MyDataPool(3);
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                Connection connection = dataPool.getConnection();
                log.info("获得链接对象:{}", connection);
                // 模拟使用时间
                MyThreadUtil.sleep(new Random().nextInt(5));
                // 归返链接
                dataPool.closeConnection(connection);
                log.info("链接已归还");
            }, "service-" + i).start();
        }
    }
}

完美!