• 连接池小实例


    工作之余看了一下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();
                } else {
                    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();
                                } else {
                                    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等待通知里面的等待队列、同步队列还有很多值得梳理的地方,后面有时间后来认真总结,今天划水就先划到这里。

  • 相关阅读:
    TFS2017持续发布中调用PowerShell启停远程应用程序
    基于BUI开发Asp.net MVC项目
    WebAPI应用问题整理
    C#多线程顺序依赖执行控制
    TFS下载文件已损坏问题
    Asp.net core中使用Session
    为什么使用.Net Core, Asp.net Core以及部署到云端
    基于微软开发平台构建和使用私有NuGet托管库
    TFS2017代码搜索功能
    [转】[tip] localhost vs. (local) in SQL Server connection strings
  • 原文地址:https://www.cnblogs.com/mrxiaobai-wen/p/14785258.html
Copyright © 2020-2023  润新知