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();
      }
      }
      }

 

完美!