享元模式与自定义连接池

本文介绍了享元模式在减少对象创建、优化内存使用中的作用,并通过自定义数据库连接池的实现展示了两种版本:synchronized同步锁版和Semaphore信号量版。在测试中,两个版本分别展示了如何管理和重用数据库连接,以提高系统性能。通过对比,讨论了不同同步策略对并发性能的影响。
摘要由CSDN通过智能技术生成

享元模式

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。

何时使用: 1、系统中有大量对象。 2、这些对象消耗大量内存。 3、这些对象的状态大部分可以外部化。 4、这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。 5、系统不依赖于这些对象身份,这些对象是不可分辨的。

应用实例: 1、JAVA 中的 String,如果有则返回,如果没有则创建一个字符串保存在字符串缓存池里面。(可参照前博文) 2、数据库的数据池。

自定义连接池

synchronized版

/**
 *@ClassName CustomDataBasePool
 *@Description 自定义数据库连接池 享元模式 synchronized版
 **/
public class CustomConnectionPoolTest {

    public static void main(String[] args) {
        //测试代码
        CustomConnectionPool pool = new CustomConnectionPool(2);
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                Connection conn = null;
                try {
                    conn = pool.getConn();
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                pool.backConn(conn);
            },"线程"+i).start();
        }
    }

}
@Slf4j
class CustomConnectionPool {
    private final int poolSize;
    private Connection[] connections;
    //用于记录每个连接是否被占用 0 表示未被占用, 1表示已被占用
    private final AtomicIntegerArray stateArr;
    private final Semaphore semaphore;

    public CustomConnectionPool(int poolSize) {
        this.poolSize = poolSize;
        semaphore = new Semaphore(poolSize);
        stateArr = new AtomicIntegerArray(new int[poolSize]);
        connections = new Connection[poolSize];
        for (int i = 0; i < connections.length; i++) {
            connections[i] = new CustomConnection("连接" + i );
        }
    }

    public Connection getConn() throws InterruptedException {
        while (true) {
            for (int i = 0; i < poolSize; i++) {
                if (stateArr.get(i) == 0 && stateArr.compareAndSet(i, 0, 1)) {
                    log.info("拿到连接");
                    return connections[i];
                }
            }
            synchronized (this) { //如果未获取到连接,则进入阻塞状态等待被唤醒重新获取连接
                try {
                    log.info("进入wait");
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void backConn(Connection conn) {
        for (int i = 0; i < connections.length; i++) {
            if (connections[i] == conn) {
                log.info("归还连接");
                stateArr.set(i, 0);
                synchronized (this) { //归还后唤醒所有阻塞等待获取连接的线程
                    this.notifyAll();
                }
            }
        }
    }
}

@Slf4j
class CustomConnection implements Connection {

    private String name;

    public CustomConnection(String name) {
        log.info("自定义{}创建成功",name);
        this.name = name;
    }

    public String getName() {
        return name;
    }

    /** 此处打断重写代码忽略*/
}

测试结果:
在这里插入图片描述

Semaphore版

/**
 *@ClassName CustomDataBasePool
 *@Description 自定义数据库连接池 享元模式
 **/
public class CustomConnectionPoolTest {

    public static void main(String[] args) {
        //测试代码
        CustomConnectionPool pool = new CustomConnectionPool(2);
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                Connection conn = null;
                try {
                    conn = pool.getConn();
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                pool.backConn(conn);
            },"线程"+i).start();
        }
    }

}
@Slf4j
class CustomConnectionPool {
    private final int poolSize;
    private Connection[] connections;
    //用于记录每个连接是否被占用 0 表示未被占用, 1表示已被占用
    private final AtomicIntegerArray stateArr;
    private final Semaphore semaphore;

    public CustomConnectionPool(int poolSize) {
        this.poolSize = poolSize;
        semaphore = new Semaphore(poolSize);
        stateArr = new AtomicIntegerArray(new int[poolSize]);
        connections = new Connection[poolSize];
        for (int i = 0; i < connections.length; i++) {
            connections[i] = new CustomConnection("连接" + i );
        }
    }

    public Connection getConn() throws InterruptedException {
        semaphore.acquire();
        for (int i = 0; i < poolSize; i++) {
            if (stateArr.get(i) == 0 && stateArr.compareAndSet(i, 0, 1)) {
                log.info("拿到连接");
                return connections[i];
            }
        }
        return null;
    }

    public void backConn(Connection conn) {
        for (int i = 0; i < connections.length; i++) {
            if (connections[i] == conn) {
                log.info("归还连接");
                stateArr.set(i, 0);
                semaphore.release();
            }
        }
    }
}

@Slf4j
class CustomConnection implements Connection {

    private String name;

    public CustomConnection(String name) {
        log.info("自定义{}创建完成",name);
        this.name = name;
    }

    public String getName() {
        return name;
    }

     /** 此处打断重写代码忽略*/
}

测试结果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@晴天_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值