JUC的数据库连接池小练习

2022/5/11 2:01:08

本文主要是介绍JUC的数据库连接池小练习,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

JUC练习数据库连接池实现

  • 通过一个连接数组来充当连接池
  • 一个原子的标记数组
  • 通过cas来保持多线程下的安全,用synchronized来进行暂停和唤醒
@Slf4j
public class MyConnectionPoll {

    // 连接池对象数组
    private Connection[] connections;
    // 使用标记
    private AtomicIntegerArray flagArrays;
    // 线程池大小
    private Integer poolSize;

    public MyConnectionPoll(){
        this.poolSize = 5;
        connections = new MarkConnection[5];
        flagArrays = new AtomicIntegerArray(5);
        for (int i = 0; i < connections.length; i++) {
            connections[i] = new MarkConnection("连接" + i+1);
        }
    }

    // 连接池的初始化
    public MyConnectionPoll(int poolSize) {
        this.poolSize = poolSize;
        connections = new MarkConnection[poolSize];
        flagArrays = new AtomicIntegerArray(poolSize);
        for (int i = 0; i < connections.length; i++) {
            connections[i] = new MarkConnection("连接" + i);
        }
    }

    // 向连接池中请求连接
    public Connection getConnection(){
        while (true){
            for (int i = 0; i < poolSize; i++) {
                // 进行cas请求,如果请求失败就失败
                if (flagArrays.compareAndSet(i,0,1)){
                    return connections[i];
                }
            }
            // 如果请求失败,并且已经没有可用的连接就需要进行等待
            synchronized (this){
                try {
                    // 等待直到被唤醒,然后对所有请求进行遍历找到空闲连接
                    this.wait();  // 调用wait方法需要进行加锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 释放连接
    public void releaseConnection(Connection con){
        for (int i = 0; i < poolSize; i++) {
            if (con == connections[i]){
                flagArrays.set(i,0);  // 将连接标识置为0即空间连接
                synchronized (this){
                    this.notifyAll(); // 唤醒全部等待的线程
                }
            }
        }
    }

    public static void main(String[] args) {
        MyConnectionPoll myConnectionPoll = new MyConnectionPoll(5);
        for (int i = 0; i < 10; i++) {
            new Thread(() ->{
                MarkConnection connection =(MarkConnection) myConnectionPoll.getConnection();
                log.debug("获得锁{}",connection.getConName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                myConnectionPoll.releaseConnection(connection);
                log.debug("释放锁{}",connection.getConName());
            }).start();
        }
    }
}


这篇关于JUC的数据库连接池小练习的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程