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

1.背景

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

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

2.连接池具体实现

1.jdbc链接的实例对象

/**
 * @author 姿势帝-博客园
 * @address https://www.cnblogs.com/newAndHui/
 * @WeChat 851298348
 * @create 02/19 8:17
 * @description
 * <p>
 *     模拟一个实现jdbc链接的实例
 * </p>
 */
@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 <p>
 * 自定义一个数据库连接池
 * 练习多线程,原子性等概念的理解
 * </p>
 */
@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();
        }
    }
}

 

完美!

posted @ 2022-02-19 21:08  李东平|一线码农  阅读(453)  评论(0编辑  收藏  举报