Java 模拟数据库连接池的实现代码
前面学习过等待-通知机制,现在我们在其基础上添加一个超时机制,模拟从连接池中获取、使用和释放连接的过程。客户端获取连接的过程被设定为等待超时模式,即如果在1000毫秒内无法获取到可用连接,将会返回给客户端一个null。设定连接池的大小为10个,然后通过调节客户端的线程数来模拟无法获取连接的场景
由于java.sql.Connection只是一个接口,最终实现是由数据库驱动提供方来实现,考虑到本例只是演示,我们通过动态代理构造一个Connection,该Connection的代理仅仅是在调用commit()方法时休眠100毫秒
publicclassConnectionDriver{ staticclassConnectionHandlerimplementsInvocationHandler{ @Override publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{ if("commit".equals(method.getName())){ TimeUnit.MICROSECONDS.sleep(100); } returnnull; } } /** *创建一个Connection的代理,在commit时休眠100毫秒 */ publicstaticConnectioncreateConnection(){ return(Connection)Proxy.newProxyInstance(ConnectionDriver.class.getClassLoader(), newClass>[]{Connection.class},newConnectionHandler()); } }
接下来是线程池的实现。本例通过一个双向队列来维护连接,调用方需要先调用fetchConnection(long)方法来指定在多少毫秒内超时获取连接,当连接使用完成后,需要调用releaseConnection(Connection)方法将连接放回线程池
publicclassConnectionPool{ privatefinalLinkedListpool=newLinkedList<>(); publicConnectionPool(intinitialSize){ //初始化连接的最大上限 if(initialSize>0){ for(inti=0;i 0){ pool.wait(remaining); remaining=future-System.currentTimeMillis(); } Connectionresult=null; if(!pool.isEmpty()){ result=pool.removeFirst(); } returnresult; } } } }
最后编写一个用于模拟客户端获取连接的示例,该示例将模拟多个线程同时从连接池获取连接,并记录总尝试获取数、获取成功数和获取失败数
publicclassConnectionPoolTest{ staticConnectionPoolpool=newConnectionPool(10); staticCountDownLatchstart=newCountDownLatch(1); staticCountDownLatchend; publicstaticvoidmain(String[]args)throwsInterruptedException{ //线程数量 intthreadCount=200; end=newCountDownLatch(threadCount); intcount=20; AtomicIntegergot=newAtomicInteger(); AtomicIntegernotGot=newAtomicInteger(); for(inti=0;i0){ try{ //从线程池中获取连接,如果1000ms内无法获取到,将返回null //分别统计获取连接的数量got和未获取到的数量notGot Connectionconnection=pool.fetchConnection(1000); if(connection!=null){ try{ connection.createStatement(); connection.commit(); }finally{ pool.releaseConnection(connection); got.incrementAndGet(); } }else{ notGot.incrementAndGet(); } }catch(Exceptione){ e.printStackTrace(); }finally{ count--; } } end.countDown(); } } }
笔者设置线程数量为200时,得出结果如下
当设置为500时,得出结果如下,当然具体结果根据机器性能而异
可见,随着客户端线程数的增加,客户端出现超时无法获取连接的比率不断升高。这种等待超时模式能保证程序出问题时,线程不会一直运行,而是按时返回,并告知客户端获取连接出现问题。数据库连接池的实际也可以应用到其他资源获取的场景,针对昂贵资源的获取都应该加以限制
到此这篇关于Java模拟数据库连接池的实现代码的文章就介绍到这了,更多相关Java数据库连接池内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。