JUC:实现一个简易的数据库连接池(享元模式)

主要是学习享元模式。  

享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享尽可能多的对象来最小化内存使用和提高性能。在该模式中,对象被分为两种状态:内部状态和外部状态。

  • 内部状态(Intrinsic State):内部状态是对象可以共享的状态,它存储在享元对象内部,并且不随环境的变化而改变。因此,可以被多个对象共享。

  • 外部状态(Extrinsic State):外部状态是对象的上下文相关的状态,它取决于对象被使用的环境,并且无法共享。客户端需要在使用享元对象时提供外部状态。

        享元模式的核心思想是将对象中共享的状态提取出来,存储在一个共享池中,当需要创建对象时,首先检查是否存在具有相同内部状态的对象。如果存在,则直接返回共享对象,否则创建新对象并加入共享池中。

        这种方式可以有效地减少内存消耗,特别是当需要创建大量相似对象时。典型的应用场景包括文本编辑器中的字符对象、游戏中的粒子对象等。

        在实现享元模式时,需要注意对内部状态和外部状态的管理,以及线程安全等问题。

        预先创建好一批连接,放入连接池。一次请求到达后,从连接池获取连接,使用完毕后再还回连接池,

        这样既节约了连接的创建和关闭时间,也实现了连接的重用,不至于让庞大的连接数压垮数据库。


package com.数据库连接池;

import java.sql.*;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;

public class test {
    public static void main(String[] args) {

        Pool pool = new Pool(3);

        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                Connection conn = pool.borrow();
                try {
                    Thread.sleep(new Random().nextInt(1000)); // 模拟使用随机的时间后,进行归还
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                pool.free(conn);
            }).start();
        }
    }
}

class Pool {

    // 连接池大小
    private final int poolSize;

    // 连接对象数组
    private Connection[] connections;

    // 连接状态,线程安全的
    private AtomicIntegerArray states;

    public Pool(int poolSize) {
        this.poolSize = poolSize;
        this.connections = new Connection[poolSize];
        this.states = new AtomicIntegerArray(new int[poolSize]);
        for (int i = 0; i < poolSize; i++) {
            connections[i] = new MockConnection();
        }
    }

    // 借连接
    public Connection borrow() {
        while (true) {
            for (int i = 0; i < poolSize; i++) {
                if (states.get(i) == 0) {
                    if (states.compareAndSet(i, 0, 1)) { // cas成功才return,不要直接set,防止多线程读写分离
                        System.out.println(Thread.currentThread().getName() + "借到了连接");
                        return connections[i];
                    }
                }
            }
            // 没有空闲连接,进入等待
            System.out.println(Thread.currentThread().getName() + "没有空闲连接,进入等待");
            synchronized (this) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 归还连接
    public void free(Connection connection) {

        for (int i = 0; i < poolSize; i++) {
            if (connections[i] == connection) {
                states.set(i, 0); // 这里不用cas,归还线程一定是唯一拥有它的线程
                System.out.println(Thread.currentThread().getName() + "释放了连接");
                // 通知如果有再wait中的线程
                synchronized (this) {
                    this.notifyAll();
                }
                break;
            }
        }

    }
}
// 不用真的去连接,随便实现一下Connection用来测试即可
class MockConnection implements Connection{

    // 这里省略了,太长了
}

比较简单,可自行拓展,就不再多描述了。

相关推荐

  1. 基于模式实现连接

    2024-04-09 12:56:02       14 阅读
  2. fastapi数据库连接模版

    2024-04-09 12:56:02       15 阅读
  3. 模式理解

    2024-04-09 12:56:02       12 阅读
  4. C++中模式

    2024-04-09 12:56:02       9 阅读
  5. c++实现数据库连接

    2024-04-09 12:56:02       14 阅读
  6. 设计模式

    2024-04-09 12:56:02       37 阅读
  7. [go] 模式

    2024-04-09 12:56:02       37 阅读

最近更新

  1. https创建证书

    2024-04-09 12:56:02       0 阅读
  2. 环境瘦身术:Conda包依赖的自动清理指南

    2024-04-09 12:56:02       0 阅读
  3. Django 实现子模版继承父模板

    2024-04-09 12:56:02       0 阅读
  4. [面试爱问] https 的s是什么意思,有什么作用?

    2024-04-09 12:56:02       0 阅读
  5. Docker

    2024-04-09 12:56:02       1 阅读
  6. Vue中v-for和v-if优先级(2、3)

    2024-04-09 12:56:02       1 阅读

热门阅读

  1. 数据大屏:现代数据分析与可视化的重要工具

    2024-04-09 12:56:02       17 阅读
  2. Docker中运行ASP.NET Core应用

    2024-04-09 12:56:02       16 阅读
  3. 大家问的最多的问题统一回复

    2024-04-09 12:56:02       15 阅读
  4. 网桥设置介绍

    2024-04-09 12:56:02       15 阅读
  5. 文心一言和GPT-4横向对比

    2024-04-09 12:56:02       16 阅读
  6. docker 的使用与说明

    2024-04-09 12:56:02       16 阅读
  7. python教程(4更新中)

    2024-04-09 12:56:02       13 阅读
  8. CENTOS7安装DOCKER COMPOSE

    2024-04-09 12:56:02       16 阅读
  9. Dockerfile部署Docker项目

    2024-04-09 12:56:02       13 阅读
  10. 2024.4.9记——C++多线程系列文章(五)之死锁

    2024-04-09 12:56:02       15 阅读