连接池小实例

作者: 小白先生哦

学习连接池的一个小Demo

工作之余看了一下Java的等待通知机制原理,然后里面有一个数据库连接池的小Demo,觉得蛮有意思。所以看完之后,自己动手写了一个简单的实例,代码虽然简单,但是对于理解连接池还是小有帮助。话不多说,直接上代码。

链接占位:[后面有时间了再来总结Java的等待通知机制]


连接定义

public class Connection {
    public void execute() {
        try {
            Thread.sleep((long) (Math.random() * 10));
        } catch (InterruptedException e) {
        }
    }
}

连接驱动定义

public class ConnectionDriver {
    public static Connection createConnection() {
        return new Connection();
    }
}

连接池定义

public class ConnectionPool {
    private final LinkedList<Connection> pool = new LinkedList<>();
    public ConnectionPool(int count) {
        if (count <= 0) {
            count = 1;
        }
        for (int i = 0;i < count;i++) {
            pool.addLast(ConnectionDriver.createConnection());
        }
    }
    public Connection fetchConnection() throws InterruptedException {
        return fetchConnection(-1);
    }
    public Connection fetchConnection(int mil) throws InterruptedException {
        synchronized (pool) {
            if (mil <= 0) {
                while (pool.isEmpty()) {
                    pool.wait();
                }
                return pool.removeFirst();
                long fuTime = System.currentTimeMillis() + mil;
                long remain = mil;
                while (pool.isEmpty() && remain > 0) {
                    pool.wait(remain);
                    remain = fuTime - System.currentTimeMillis();
                }
                Connection result = null;
                if (!pool.isEmpty()) {
                    result = pool.removeFirst();
                }
                return result;
            }
        }
    }
    public void releaseConnection(Connection connection) {
        if (connection == null) {
            return;
        }
        synchronized (pool) {
            pool.addLast(connection);
            pool.notifyAll();
        }
    }
}

连接池测试

public class ConnectionPollCeshi {
    public static void main(String[] args) throws InterruptedException {
        int threadCount = 10;
        ConnectionPool pool = new ConnectionPool(5);
        CyclicBarrier start = new CyclicBarrier(1);
        CountDownLatch end = new CountDownLatch(threadCount);
        AtomicInteger gotSuccess = new AtomicInteger();
        AtomicInteger gotFailed = new AtomicInteger();
        for (int i = 0;i < threadCount;i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        start.await();
                    } catch (Exception e) { }
                    for (int i = 0;i < 10;i++) {
                        try {
                            Connection connection = pool.fetchConnection(2);
                            if (connection == null) {
                                gotFailed.incrementAndGet();
                                connection.execute();
                                pool.releaseConnection(connection);
                                gotSuccess.incrementAndGet();
                            }
                        } catch (InterruptedException e) {
                            gotFailed.incrementAndGet();
                        }
                    }
                    end.countDown();
                }
            }).start();
        }
        end.await();
        System.out.println("获取成功: " + gotSuccess.get());
        System.out.println("获取失败: " + gotFailed.get());
    }
}

运行结果

获取成功: 48
获取失败: 5

实现原理

上面使用了经典的等待通知机制,分为等待角色和通知角色,如下: 等待角色伪代码

{
  while(条件不变) {
    obj.wait();
  }
}

通知角色伪代码

{
  改变条件
  obj.notifyAll();
}

对于Java等待通知里面的等待队列、同步队列还有很多值得梳理的地方,后面有时间后来认真总结,今天划水就先划到这里。

原文创作:小白先生哦

更多推荐

更多
  • Ansible2实战-五、消费和创建模块 技术要求,使用命令行执行多个模块,查看模块索引,从命令行访问模块文档,模块返回值,开发定制模块,避免常见的陷阱,测试和记录您的模块,模块清单,向上游投稿–提交 GitHub 拉取请求,摘要,发现插件类型,问题,进一步, 在这本书里
    Apache CN

  • Ansible2实战-十、容器和云管理 技术要求,使用行动手册设计和构建容器,管理多个容器平台,使用可扩展容器部署到 Kubernetes,用 Ansible 管理 Kubernetes 对象,安装 Ansible 的库本内特依赖项,用 Ansible 列出 Kubernet
    Apache CN

  • Ansible2实战-九、使用 Ansible 的网络自动化 技术要求,为什么要自动化网络管理?,了解 ansible 如何管理网络设备,实现网络自动化,查看可用的 Ansible 网络模块,连接到网络设备,网络设备的环境变量,网络设备的条件语句,摘要,问题,进一步, 多年前,标准做法是手工
    Apache CN

  • Ansible2实战-十二、Ansible Tower 入门 技术要求,安装 AWX,运行你的第一个剧本从 AWX,创建 AWX 项目,创建库存,创建作业模板,运行作业,控制进入 AWX,创建用户,创建团队,创建组织,在 AWX 分配权限,摘要,问题, Ansible 非常强大,但它确实需要
    Apache CN

  • Ansible2实战-十一、故障排除和测试策略 技术要求,挖掘行动手册执行问题,使用主机事实诊断故障,用剧本测试,使用检查模式,解决主机连接问题,通过命令行界面传递工作变量,限制主机的执行,刷新代码缓存,检查错误的语法,摘要,问题,进一步, 与任何其他类型的代码类似,Ansib
    Apache CN

  • Ansible2实战-第三部分:在企业中使用 Ansible 在本节中,我们将从实际出发,看看如何在企业环境中最大限度地利用 Ansible。在开始使用 Ansible 管理云和容器环境之前,我们将首先了解如何使用 Ansible 自动化您的网络设备。然后,我们将了解一些更高级的测试和故障
    Apache CN

  • Ansible2实战-第二部分:扩展 Ansible 的能力 在这一节中,我们将介绍 Ansible 插件和模块的重要概念。我们将讨论它们的有效使用,以及如何通过编写自己的插件和模块来扩展 Ansible 的功能。我们甚至会考虑将您的模块和插件提交回官方 Ansible 项目的要求。我们还
    Apache CN

  • Ansible2实战-第一部分:学习 Ansible 的基础知识 在本节中,我们将了解 Ansible 的基本原理。我们将从安装 Ansible 的过程开始,然后我们将掌握基础知识,包括语言和特殊命令的基础知识。然后,我们将探索 Ansible 清单,然后再考虑编写我们的第一个行动手册和角色来
    Apache CN

  • Ansible2实战-十三、答案 第一章,第二章,第三章,第四章,第五章,第六章,第七章,第八章,第九章,第十章,破产重组保护,第十二章,第一章1.甲,乙 2.C 3.A 第二章1.C 2.B 3.A 第三章1
    Apache CN

  • Ansible2实战-八、高级 Ansible 主题 技术要求,异步与同步操作,控制滚动更新的播放执行,配置最大故障百分比,设置任务执行委托,使用一次性运行选项,在本地运行行动手册,使用代理和跳转主机,在游戏和任务中放置标签,使用可加密保管库保护数据,摘要,问题,进一步, 到目前为止
    Apache CN

  • 近期文章

    更多
    文章目录

      推荐作者

      更多