J N DI可以ai技术用于什么场景如下哪些场景?A配置信息存储,B异步信息发送,C数据库连接池查找,D远程对象查找

导读:阶段小测试-笔试试卷,D.DriverManagerDataSource比较适合在单元测试或简单的独立,《使用Java企业级技术开发大型系统》阶段小测试-笔试试卷一、选择题(共25题,每题4分,满分100分)1)下列关于Spring特性中IoC描述错误的是()。A.IoC就是指程序之间的关系由程序代码直接操控B.所谓“控制反转”是指控制权由应用代码转到外部容器,即控制权的转移C.IoC将控制创《使用Java企业级技术开发大型系统》 阶段小测试-笔试试卷 一、选择题(共25题,每题4分,满分100分) 1) 下列关于Spring特性中IoC描述错误的是(
)。 A.IoC就是指程序之间的关系由程序代码直接操控 B.所谓“控制反转”是指控制权由应用代码转到外部容器,即控制权的转移 C.IoC将控制创建的职责搬进了框架中,从应用代码脱离开来 D.使用Spring的IoC容器时只需指出组件需要的对象,在运行时Spring的IoC容器会根据XML配置数据提供给它
在Spring中,数据连接是通过数据源获得的,下列关于Spring数据源描述错误的是(
)。 A.Spring提供了一个简单的数据源实现类DriverManagerDataSource,它位于org.springframework.jdbc.datasource包中,并且这个类提供池化连接的机制 B.Spring在第三方依赖包中包含了两个数据源的实现类包,其一是Apache的DBCP,其二是C3P0 C.Spring提供引用JNDI资源的类是JndiObjectFactoryBean D.DriverManagerDataSource比较适合在单元测试或简单的独立应用中使用
3) 下列关于Spring配置文件的说法不正确的是(
)。 A.Spring默认是读取/WEB-INF/applicationContext.xml配置文件 B.Spring的配置文件可以配置在类路径下,并可以重命名,但是需要在web.xml文件中指定 C.把applicationContext.xml文件放到src目录下,Spring也可以读到 D.可以通过在web.xml中的和进行指定Spring配置文件
4) 下面关于Spring中的bean的作用域,描述错误的是(
)。 A.Spring中的bean的作用域可以通过scope属性进行配置 B.Spring中的bean的作用域默认是prototype C.当一个bean的scope设为“singleton”时,可以被多个线程同时访问 D.一个bean的scope只对它自己起作用,与其它bean无关
5) 下列关于Spring的装配模式(default-autowire)描述不正确的是(
)。 A.Spring中,至少有两种装配模式,按“类型”和“名字” B.Spring中默认是按名字进行装配的 C.可以用default-autowire=”byType”配置按类型装配 D.一旦在一个Spring配置文件中配置了default-autowire=”byType”,其它的配置文件也是按此种装配方式进行装配
6) 某业务方法taskApply(User user,List tasks)需要对其进行事务控制,下面的声明方式不能起到效果的是(
)。 A.将查询方法声明为只读事务,其他方法声明为REQUIRED B.声明do开头的方法为REQUIRED,并修改方法名为doTaskApply C.<tx:method name=\D.事务的propagation属性声明为SUPPORTS
7) 下列关于Spring与Hibernate的集成,说法错误的是(
)。 A.Spring与Hibernate的集成后,Hibernate的SessionFactory可以让Spring进行管理 B.Hibernate中的配置文件也可以移到Spring的配置文件中配置 C.使用Spring的事务管理,会让Hibernate事务处理变得简单 D.Hibernate的映射文件的路径(如:cn/jbit/project/model/User.hbm.xml),不能在Spring中定义
8) 下列关于Spring配置数据连接池的描述,错误的是(
)。 A.Spring可以用mons.dbcp.BasicDataSource类配置数据源 B.在mons.dbcp.BasicDataSource类中有driver,url,username,password属性 C.配置Spring数据源时,必须引入Hibernate的SessionFactory D.在用dbcp时,需要拷贝commons-dbcp的jar包到类路径下
9) 下列选项关于Spring的核心机制――依赖注入的描述正确的是(
)。 A.所谓依赖注入就是明确地定义组件接口,独立开发各个组件,然后根据组件间的依赖关系组装运行的设计开发模式 B.Spring不负责管理bean之间的关系 C.节点有可选的子节点,用于注入bean的属性 D.在Spring的配置文件中,使用来创建Bean的实例
10) Spring配置文件中关于事务的配置代码如下: ?
<tx:advice id=\
<tx:method name=\
read-only=\
<tx:method name=\
<tx:method name=\
<aop:pointcut id=\
expression=\
<aop:advisor advice-ref=\①________\②_________\
? 在横线处应填入(
)。 A. ① txAdvice ② txManager B. ① serviceMethod ② txManager C. ① txAdvice ② serviceMethod D. ① serviceMethod ② txAdvice
11) 下面关于Struts 2、Hibernate以及Spring整合说法正确是(
)。 A. 当我们将Hiberntae和Spring集成后,Hibernate的程序就交给Spring容器进行管理,所以我们不需要在将操作Hibernate的DAO配置在Spring容器中 B. 将Struts2、Hibernate与Spring集成后,更方便系统开发 C. 所有Spring中的配置信息必须放到applicationContext.xml 中 D. 当我们将Struts、Hibernate以及Spring整合在一起时,Spring只能管理Hibernate操作数据库的事务,并不能管理Struts中关于业务操作的事务
12) 关于Spring对Hibernate的支持,下列说法正确的是(
)。 A. Spring也提供了一个持久化解决方案,可以替代Hibernate,也可以和Hibernate集成使用 B. 使用Spring对Hibernate的支持,我们将无需创建SessionFactory C. 可以在Spring配置文件中配置Hibernate,因此Spring的配置文件和Hibernate的配置文件无法同时使用 D. Spring提供的HibernateDaoSupport类提供了SessionFactory的setter方法
13) 分析下面的Spring配置代码,可以推断下列Java语句的运行结果是(
)。 Java语句如下: ApplicationContext context=new ClassPathXmlApplicationContext(\System.out.println( ((B)context.getBean(\Spring配置代码如下: <bean id=\
<property name=\ <bean id=\
<property name=\
A. 编译错误 B. 什么也不输出 C. 输出:1 D. 输出:2
14) 在Spring配置文件di.xml中包含如下的代码 <bean id=\
<property name=\ 由此可以推断出( )。 A. 可以通过如下代码获取Test的实例 ApplicationContext context=new ClassPathXmlApplicationContext(\Test test=(Test)content.getBean(\. 可以通过如下代码获取i的值 ApplicationContext context=new ClassPathXmlApplicationContext(\int i = (int)content.getBean(\C. Test肯定实现了一个接口 D. Test中一定存在getI()方法
15) 在Spring中,关于依赖注入,下面说法错误的是(
)。 A. 依赖注入提倡面向接口编程 B. 依赖注入可降低系统的各个组件之间的依赖程度 C. 依赖注入的组件对外提供接口时,使得可以随意更换接口的实现 D. 依赖注入使得在实现组件时,必须考虑各个组件中的依赖关系
16) 在Spring中,可以通过(
)方式实现了依赖注入。 A. getter方法 B. setter方法 C. 自定义赋值方法 D. 静态方法
17) 分析如下所示的Spring配置文件中的代码,则选项中的说法正确的是(
<aop:pointcut id=\
expression=\
<aop:advisor advice-ref=\
(选择二项) A. 这是Spring 2.0风格的配置 B. 该配置不对任何方法起作用 C. 将对cn.jbit.jboa.biz包下的所有类的所有方法进行事务控制 包含总结汇报、办公文档、IT计算机、文档下载、资格考试、旅游景点、出国留学、教学研究、考试资料、专业文献、人文社科、应用文书以及Spring阶段小测试-笔试试卷等内容。本文共2页
相关内容搜索【总结】 Java程序员的学习和发展方向
一、技术积累
(1)代码规范
1.1.1、通常的模块分布:一般如果你要实现一个web应用,你从后台将数据展示到前端页面,在一个比较大的公司,你少不了跟其他项目有交集(你调用他的接口,他依赖你的接口),这样下来,整个公司有很多个模块,怎么做到很好的联系。
回到刚刚的模块分布,你的一个web应用,应当需要分成三个模块:core模块、service模块、web模块。web模块就是展示到页面,后台代码而言主要就controller层了,其他逻辑基本都放在core了,service模块就是一些接口类和参数dto等等,接口的实现类在core模块。这样下来,web模块只需要依赖service模块,同样的其他系统依赖你的接口也仅仅是依赖service模块,然后利用远程调用方式消费你的接口服务。
1.1.2、代码层级结构:针对后台服务项目,一般分为对外接口层、service层、Dao层。Dao层就是与数据库交接的接口层,service层主要调用Dao或者外部系统的接口,复杂的逻辑基本都放在service层;一些方法需要提供给其他模块调用的时候,就封装在对外接口层,只有对外接口层是暴露。这里说的只是层级结构,还有与层级结构无关的,也是需要归类的,比如对外部系统接口方法封装的我们放在一个目录下面,一些常量和工具类等我们放在common目录下面。当然还有其他考虑,尽量让整个模块有层次感,代码才不会太乱,更好的维护。
1.1.3、总结上面两点:可能不少猿友觉得上面啰嗦又不像代码规范,其实这两点也是代码规范的一部分,主要引导大家往结构清晰好维护的思维方向走,多思考吧。
1.1.4、对于一些需要异步处理的,不要直接new一个thread,应当使用线程池。使用线程池的时候应当对线程数量大小合理设置,一般最大不超过50个,当然还需要考虑你的IO和CPU,怎么分析网上搜搜吧。
1.1.5、容器类变量,如果变化比较大且频繁,尽量定义的时候设置初始容量大小,减少扩容带来的消耗。
1.1.6、分支判断if…else的时候,最常符合的条件处理放在前面。
1.1.7、对象比较的时候常量放前面,养成好习惯,减少空指针的出现。
1.1.8、减少synchronized中等待处理的代码,能放在外面就尽量放在外面。
1.1.9、下面到数据库了,我觉得还是在这里说了好点,一般查询比较慢,很有可能是没有建索引或者索引没用到,多去检查一下。
1.1.10、两个大表的关联查询,可以使用二次访问数据库替代,先查出A表的数据,利用关联字段再查B表的。不要一味想着一条sql搞定最好。
1.1.11、坚决避免,查全表数据或者数量大的数据,返回list加载到内存中,一不小心查了100w数据,又查得比较频繁,内存的爆了。有这种风险的改成分页查询。
1.1.12、不要select *,按需取列。
1.1.13、多考虑避免事务里面有长连接或者长事务,如果大量这种情况出现占用数据连接,会影响性能。一些无必要的逻辑可以放到事务外执行。
1.1.14、对字段的加减乘除处理放到sql,严格避免先get处理,然后运算在set到数据库里面,并发情况非常容易导致失真。
1.1.15、方法里面代码不要太长,注意封装,命名语义化,代码整洁。常挂嘴边的,没放心上,一如既往的给自己埋坑,举个博主的例子,那会刚毕业也是没放心上,关注公众号:Java编程精选,最近把我们组长不写代码,一到代码评审我就害怕,检视到有问题的代码,毕业生吧就说这代码以前就是这样写的,问题最终肯定都落我身上,现在感觉代码是自己的孩子,只能有空自己偷偷的优化一下,怕出问题还得非常仔细。
(2)SQL规范与性能优化
1.2.1、先提前声明,博主工作用到是MySQL,可能有些场景只针对MySQL。说到SQL优化,一些概念必须要理解,不然死记硬背一两天就忘记了。特别是执行计划的概念。
1.2.2、什么是执行计划:a.决定如何访问表数据,是否通过索引,是否排序等。b.多表关联是先访问哪个表。c.多表关联时,使用哪种连接方式,不过现在MySQL只有嵌套连接(嵌套循环,顾名思义就是将一个表为出发点,将该表全部记录逐条去遍历另外一张表的记录)。
1.2.3、SQL执行顺序:a.检查语法是否正确。b.检查表是否存在、权限是否满足等。c.根据统计信息(如data length,rows,index length、索引唯一度),生成较优的执行计划。d.根据执行计划,进行数据检索、过滤、合并、排序等操作。访问数据时,内存中如存在表数据,则直接进行操作;否则,从磁带读取表数据,放入内存,再进行操作;如内存不足,则内存中较冷数据涮出内存,再从内存中读取数据。
1.2.4、索引:查询的时候如果使用上了索引,可以提高效率,因为建立了索引后,可以理解为数据字典的结构存储,因此根据条件查询的时候更加高效。下面看一下MySQL常用的索引类型的概念。
a.普通索引:在创建普通索引时,不附加任何限制条件。这类索引可以创建在任何数据类型中,其值是否唯一和非空由字段本身的完整性约束条件决定。建立索引以后,查询时可以通过索引进行查询。例如,在student表的stu_id字段上建立一个普通索引。查询记录时,就可以根据该索引进行查询。
b.唯一性索引:使用UNIQUE参数可以设置索引为唯一性索引。在创建唯一性索引时,限制该索引的值必须是唯一的。例如,在student表的stu_name字段中创建唯一性索引,那么stu_name字段的值就必需是唯一的。通过唯一性索引,可以更快速地确定某条记录。主键就是一种特殊唯一性索引。
c.单列索引:在表中的单个字段上创建索引。单列索引只根据该字段进行索引。单列索引可以是普通索引,也可以是唯一性索引,还可以是全文索引。只要保证该索引只对应一个字段 即可。
d.多列索引:多列索引是在表的多个字段上创建一个索引。该索引指向创建时对应的多个字段,可以通过这几个字段进行查询。但是,只有查询条件中使用了这些字段中第一个字段时,索引才会被使用。例如,在表中的id、name和sex字段上建立一个多列索引,那么,只有查询条件使用了id字段时该索引才会被使用。
e . 全文索引:使用FULLTEXT参数可以设置索引为全文索引。全文索引只能创建在CHAR、VARCHAR或TEXT类型的字段上。查询数据量较大的字符串类型的字段时,使用全文索引可以提高查询速度。例如,student表的information字段是TEXT类型,该字段包含了很多的文字信息。在information字段上建立全文索引后,可以提高查询information字段的速度。MySQL数据库从3.23.23版开始支持全文索引,但只有MyISAM存储引擎支持全文检索。在默认情况下,全文索引的搜索执行方式不区分大小写。但索引的列使用二进制排序后,可以执行区分大小写的全文索引。
还有空间索引,平时也比较少用。目前只有MyISAM存储引擎支持空间检索。目前博主也只接触过InnoDB存储引擎。
1.2.5、一般一张表索引不要超过5个,而且避免重复索引,而且也不是建了索引,根据索引字段条件查询,索引就会起作用。
1.2.6、一般哪些场景会导致索引失效:a.使用like关键字匹配字符串第一个为”%”的场景。b.条件中包含or、in、not in、&&关键字,默认不走索引的。c.访问表上的数据行超出表总记录数30%,变成全表扫描。d.查询条件使用函数在索引列上,或者对索引列进行运算。e.多列索引中,第一个索引列使用范围查询,只能用到部份或无法使用索引。f.多列索引中,第一个查询条件不是最左索引列,上面多列索引概念中也有提到。肯定还有更多的场景,但是博主现在能想到的场景就这些了。
1.2.7、不能同时使用两个索引,一个过滤数据,一个用于排序(主键除外)。
1.2.8、DML语句如果使用索引,会导致lock全表;如果使用了非唯一索引,可能只是锁住一定范围。对此,建议更新/删除数据尽量用上索引,如果可以最好用上主键或唯一索引,另外事务要及时提交。
(3)关于事务的一些建议
如果没有听过事务这么个概念,网上了解学习一下,先理解一下各个事务类型的含义吧:a.日志记录尽量放在独立事务里面,避免后面的异常发生导致日志丢失。b.上面已经几次提到,尽早提交事务,避免事务过长,因此写代码的时候,一些可以不放到事务的逻辑可以移到外面,长事务看能否拆成两个事务。
(4)关于数据库连接池
可能一些猿友都少去注意吧。先来看看一些参数,这里只罗列了博主比较关注的,更多的可以自行查看一下配置。
initialSize : 默认值是 0, 连接池创建连接的初始连接数目。 minIdle : 默认是 0, 连接数中最小空闲连接数。
maxIdle : 默认是 8 ,连接池中最大空闲连接数。
maxActive : 默认值是 8, 连接池中同时可以分派的最大活跃连接数。
maxWait : 默认值是无限大,当连接池中连接已经用完了,等待建立一个新连接的最大毫秒数 ( 在抛异常之前 )。
validationQuery : 一条 sql 语句,用来验证数据库连接是否正常。这条语句必须是一个查询模式,并至少返回一条数据。一般用“ select 1 ”。
minEvictableIdleTimeMilis : 默认值是 1000 * 60 * 30(30 分钟 ) 单位也是毫秒,连接池中连接可空闲的时间。
timeBetweenEvictionRunsMilis : 默认值是 -1 ,每隔一段多少毫秒跑一次回收空闲线程的线程。
对于minEvictableIdleTimeMilis、timeBetweenEvictionRunsMilis这两个参数,timeBetweenEvictionRunsMilis必须大于1且小于minEvictableIdleTimeMilis,建议是minEvictableIdleTimeMilis的五分之一或十分之一。
(5)对于前端的几点建议
1.7.1、一些图片压缩后再使用,性能方面提高不小吧(可以使用熊猫图片压缩)。虽然自己前端比较菜,但是估计也有不少猿友跟我一样偶尔需要兼顾前端吧。毕竟刚毕业不久。
1.7.2、关于移动端页面重构兼容不同屏幕大小的问题,建议doc的fontSize,实时获取屏幕的宽度,然后除以320再乘以16,当然16可以根据自己情况去调。然后其他一些单位尽量用rem,这样无论什么大小的屏幕都等比例缩放。感觉比@media效果好很多。
关于技术积累这一块,之前罗列的提纲还挺多的,写到后面感觉没什么精力了,有些三言两语似乎说不清楚啊。
二、工作心得
(1)沟通协作第一:
工作中必然少不了团队协作,积极主动去沟通的人做事总是更加靠谱。道理大家都懂。但是我们需要把想法问题,简洁明确的表达给对方。另外总是以沟通的心态面对问题,而不是抱怨。如果觉得上级分配的任务难度太大了,你可以尝试跟他沟通,获取他有很好的建议或解决方案。
(2)谨慎记录与排漏:
感觉现在挺经常是开一两个会,测试同时偶尔找你排查一下环境问题,一天下来其实写代码的时间并不多。一些关键点,非常建议提前记录下来,方便接回被打断的思路,同时避免一些逻辑或功能点的遗漏。
(3)思路清晰与效率:
建议动手写代码之前,建议先理清思路,关键逻辑,需求细节,这样后面写代码的时候效率比较高,而且质量也比较好。
(4)主动与多管闲事:
清楚自己的工作范围,自己心里有个界限,有些属于别人工作范围的事情,可以你提出的建议是好的,但是最好还是在合适的场景和时机提出。
(5)心态与工作状态:
程序员,总会有被坑的时候,或者不顺心的时候,尽量尝试控制一下自己的心态。
(6)可持续发展观看待技术与业务:
这点是我自己希望做到的。对于责任心而言,或者是说一个优秀的程序员。很多时候并不是完成产品提的需求就好了。多为它着想,代码可维护性和扩展性高不高。一些功能点也可以提出自己的想法,不要总是被动的接受产品的需求,业务功能拓展性好的话,可以减少产品改动需求。
三、学习方向与职业发展
(1)先广后深还是先深后广:
对于博主而言,其实接触的技术点还算比较多的,但是了解的都不深入,个人性格而言,比较偏向于实用驱动,如果在实际使用场景有用到再去深入学习,这样边学边用才能比较集中注意力。像一些同事,他们喜欢把一样东西研究得很深。
(2)业务经验也应当注重:
技术人员必然是技术优先,但是等你到了一定工作年限,其实业务经验也是非常重要了。之前领导找我年度工作谈话就有说过他们招高级工程师的时候对业务经验也非常看重,是否有自己独特的见解。相信道理大家都懂,但是平时有没有这样的意识,有没有去做又是另外一方面了。平时也可以多学习业务方面的知识。
(3)相同的工作年限为什么当过项目经理的人更吃香:
因为他们对业务理解更加深入,代码质量问题落在他头上,项目的人员协调与时间安排规划,责任越大,思考的问题就越多,遇到的问题处理经验就越丰富。把控能力也比较强。
(4)怎样能进入学习状态,并且坚持:
要想集中注意力学习技术,需要安静的环境,需要耐得住寂寞,因此你需要没有人打扰的环境,比如在一个集体居住环境,几个朋友一起住,一般多数回想着去哪玩,朋友在玩游戏,估计也是对你的一种诱惑吧。可以早点到办公室学习或下班学习一段时间再回去。或者选择自己一个人住。
(5)如何把握住学习的时机:
学习最能集中注意力的情况是有着比较强的好奇心和求知欲。所以一般一些技术分享或者老员工讨论的问题,可能很多概念知识你都不懂,这时候你就可以去学习了解这些知识。或者你工作中遇到的问题,尽量刨根问底的去弄清楚是什么原因导致的,不要一些老司机帮忙解决了就一了了之。或者是其他同事遇到的问题,你都可以去了解一下。
(6)你更适合走一条怎样的职业道路:
刚毕业不久的猿友,一般都是会比较心浮气躁的,对技术求知欲很强,特别是一些高大上的技术,什么大数据、云计算、架构等等,有些偏向于技术研究,有些偏向于业务。大部分程序员可能都会选择偏向于技术研究的,于是乎对偏向业务的不怎么感冒,因此觉得天天做这些东西没什么意思。这时候,静下来分析一下,你到底适合哪种方向。你能否静下心来对技术研究很深入,能否耐得住寂寞。
四、关于生活
(1)良好与糟糕的生活状态的区别:
需要警惕一下自己是否进入了一种糟糕的生活状态,工作上不温不火,似乎现在的技术已经足够用了,完全没有目标没有计划,无法集中注意力学习,日子就这样一天天过去。
(2)17年自己的一些期望吧:
希望活得更坚定些,保持着一定的求知欲和规划,向成为自己希望成为的人努力吧,包括一些习惯、处事方式等等。
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点数据库连接池设计
关于数据库连接池,一直都是折腾服务端程序员的问题,一般而言很多现成的框架或者类库都已经帮助我们解决了很多。
但是作为一个开发人员,我们不能仅仅现在于对框架的使用上面,要学会如何去设计连接池,明白连接池的关键原理,这样我们才能在日后的开发工作中得心应手。
&一、首先,为什么要用连接池?
1.尽管本博客前面几篇文章都已经提到过,但是现在还是要再次提下,
就一般性而言与数据库打交道的应用程序包含以下步骤:
(1).初始化程序
(2).用户在UI上面进行操作
(3).由用户操作产生数据库操作
(4).将数据库操作递交到数据库服务器
(5).重复2~4
(6).关闭应用程序
上面的第4步骤,我们很多的应用(包括本人很长的一段时间内都是这样),每一个请求过来=》建立连接=》打开连接=》操作数据库=》返回结果=》关闭数据库连接;
然而这样子的操作,对我们的应用而言效率是极其低下的甚至引起数据库崩溃~~~,或许我们可以换一种方式,它相当于另一种操作数据库的形式,然程序一开始就建
立了数据库连接,直到应用程序死亡。但是这样做也会存在很多安全性的隐患,因为我们不能保证一个对象会在内存中长期稳定下去。
  使用连接池,我们就能极大优化数据库性能问题而且保持其稳定性。
2.连接池原理:&
  对于共享资源,我们可以使用一个非常著名的设计模式:资源池(Resource Pool);对应于我们的数据库,基本的思想就是为数据库建立一个数据库连接池,即相当于一个缓
冲池,我们预先在数据库连接池中放入一定数量的连接,当需要建立数据库连接时,只需从&缓冲池&中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防
止系统无尽的与数据库连接。比如说我们设定数据库连接池的最大数量为100,到101个请求来,这个连接只能等待,而不会增加新的连接,于此类推102、103三都统一加到等待
队列,&&&&&&&待数据库连接池中有空闲然后再在连接池里面取到一个连接,付给第101个请求&&&
3.数据库连接池一般性问题:
(1)并发问题:
  为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。这个问题相对比较好解决,因为各个语言自身提供了对并发管理的支持像java,c#等等,使用synchronized(java)/lock(C#)关键字即可确保线程是同步的。(ps:关于synchronized(java)/lock(C#):之前那段时间我也纠结了很久,synchronized意思为同步,而lock是锁,从程序运行的角度synchronized合适一点,但是从资源管理上lock确显得更加好,lock对应资源的锁,保证资源的互斥性。就本人而言个人更加喜欢C#的方式,因为理解上更加的容易)
&(2)事务处理
  事务操作是具有原子性的,此时要求数据库操作符合"ALL-ALL-NOTHING"原则,即对一组SQL语句要么全做,要么全不做;假设有两个线程公用一个数据库连接,因为我们不能确定那个事务对应那个数据库操作,因此对应事务而言,我们采取一对一策略,即:每个事务独占一个数据库连接
&(3)连接池的分配与释放
&  连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。
&  对于连接的管理可以使用一个List。即把已经创建的连接都放到List中统一管理。每当用户请求一个连接时,系统检查这个List中有没有可以分配的连接。如果有就把那个最合适的连接分配给他。如果没有就抛出一个异常给用户,List中连接是否可以被分配由一个线程来专门管理捎后我会介绍这个线程的具体实现。
&(4)连接池的分配与维护
  连接池中到底应该放置多少连接,才能使系统的性能最佳?系统可采取设置最小连接数(minConnection)和最大连接数(maxConnection)等参数来控制连接池中的连接。比方说,最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快;如果创建过少,则系统启动的很快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。最大连接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过软件需求上得到。  如何确保连接池中的最小连接数呢?有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。
&(5)连接复用
在分配、释放策略对于有效复用连接非常重要,我们采用的方法也是采用了一个很有名的设计模式:Reference Counting(引用记数)。
&采取策略:
&1.ConnLevel_ReadOnly 独占方式
&2.ConnLevel_High 优先级-高
&3.ConnLevel_None 优先级-中
&4.ConnLevel_Bottom 优先级-底
&(6)实现事务采取独占方式
(7)管理连接池
  在上文中我们说过这个连接池内部连接管理使用的是独立的线程来工作(threadCreate和threadCheck)threadCreate线程负责创建连接&,threadCheck线程负责检查每个连接是否达到自己的寿命,标志连接寿命的条件是被引用的次数超过它最大被引用次数,或者达到最大生存时间。这些参数都由ConnStruct类管理
  当用户调用连接池的StartService方法时,在StartService方法中会通知threadCreate线程创建静态连接,然后将这些静态连接加入到List,同时启动threadCheck线程,threadCheck线程负责检测List中的最小空闲连接是否少于连接池配置的最少空闲连接数,当条件为真时threadCheck线程会负责再次唤醒threadCreate线程同时给threadCreate线程传递这次要创建的连接个数。  对于threadCreate线程有2种工作模式,模式0为初始化创建模式,该模式会创建连接迟池配置的最小连接数目;模式1即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接时的工作模式。  申请连接,当用户申请连接时必须指定一个发起者和一个申请优先级别,优先级由ConnLevel_*系列指定。一旦用户从连接池中申请到一个连接时就将申请到的连接引用和申请者,同时加入到HashTable来注册到连接池。
管理类为:
using System.C
using System.T
using System.D
namespace CommonTools
/// &summary&
/// 连接池状态
/// &/summary&
public enum PoolState
/// &summary&
/// 刚刚创建的对象,表示该对象未被调用过StartSeivice方法。
/// &/summary&
UnInitialize,
/// &summary&
/// 初始化中,该状态下服务正在按照参数初始化连接池。
/// &/summary&
Initialize,
/// &summary&
/// 运行中
/// &/summary&
/// &summary&
/// 停止状态
/// &/summary&
/// &summary&
/// 要申请连接的级别
/// &/summary&
public enum ConnLevel
/// &summary&
/// 独占方式,分配全新的连接资源,并且该连接资源在本次使用释放回连接池之前不能在分配出去。如果连接池只能分配引用记数类型连接资源则该级别将产生一个异常,标志连接池资源耗尽
/// &/summary&
/// &summary&
/// 优先级-高,分配全新的连接资源,不使用引用记数技术。注:此级别不保证在分配后该连接资源后,仍然保持独立占有资源,若想独立占有资源请使用ReadOnely
/// &/summary&
/// &summary&
/// 优先级-中,适当应用引用记数技术分配连接
/// &/summary&
/// &summary&
/// 优先级-底,尽可能使用引用记数技术分配连接
/// &/summary&
/// &summary&
/// 连接类型
/// &/summary&
public enum ConnTypeEnum
/// &summary&
/// ODBC 数据源
/// &/summary&
/// &summary&
/// OLE DB 数据源
/// &/summary&
/// &summary&
/// SqlServer 数据库连接
/// &/summary&
SqlClient,
/// &summary&
/// 默认(无分配)
/// &/summary&
/// &summary&
/// 连接池中的一个连接类型
/// &/summary&
public class ConnStruct : IDisposable
/// &summary&
/// 连接池中的连接
/// &/summary&
/// &param name="dbc"&数据库连接&/param&
/// &param name="cte"&连接类型&/param&
public ConnStruct(DbConnection dbc, ConnTypeEnum cte)
createTime = DateTime.N
connType =
/// &summary&
/// 连接池中的连接
/// &/summary&
/// &param name="dt"&连接创建时间&/param&
/// &param name="dbc"&数据库连接&/param&
/// &param name="cte"&连接类型&/param&
public ConnStruct(DbConnection dbc, ConnTypeEnum cte, DateTime dt)
createTime =
connType =
//--------------------------------------------------------------------
private bool enable = true;//是否失效
private bool use = false;//是否正在被使用中
private bool allot = true;//表示该连接是否可以被分配
private DateTime createTime = DateTime.N//创建时间
private int useDegree = 0;//被使用次数
private int repeatNow = 0;//当前连接被重复引用多少
private bool isRepeat = true;//连接是否可以被重复引用,当被分配出去的连接可能使用事务时,该属性被标识为true
private ConnTypeEnum connType = ConnTypeEnum.N//连接类型
private DbConnection connect = null;//连接对象
private object obj = null;//连接附带的信息
#region 属性部分
/// &summary&
/// 表示该连接是否可以被分配
/// &/summary&
public bool Allot
get { return }
set { allot = }
/// &summary&
/// 是否失效;false表示失效,只读
/// &/summary&
public bool Enable
{ get { return } }
/// &summary&
/// 是否正在被使用中,只读
/// &/summary&
public bool IsUse
{ get { return } }
/// &summary&
/// 创建时间,只读
/// &/summary&
public DateTime CreateTime
{ get { return createT } }
/// &summary&
/// 被使用次数,只读
/// &/summary&
public int UseDegree
{ get { return useD } }
/// &summary&
/// 当前连接被重复引用多少,只读
/// &/summary&
public int RepeatNow
{ get { return repeatN } }
/// &summary&
/// 得到数据库连接状态,只读
/// &/summary&
public ConnectionState State
{ get { return connect.S } }
/// &summary&
/// 得到该连接,只读
/// &/summary&
public DbConnection Connection
{ get { return } }
/// &summary&
/// 连接是否可以被重复引用
/// &/summary&
public bool IsRepeat
get { return isR }
set { isRepeat = }
/// &summary&
/// 连接类型,只读
/// &/summary&
public ConnTypeEnum ConnType
{ get { return connT } }
/// &summary&
/// 连接附带的信息
/// &/summary&
public object Obj
get { return }
set { obj = }
#endregion
/// &summary&
/// 打开数据库连接
/// &/summary&
public void Open()
{ connect.Open(); }
/// &summary&
/// 关闭数据库连接
/// &/summary&
public void Close()
{ connect.Close(); }
/// &summary&
/// 无条件将连接设置为失效
/// &/summary&
public void SetConnectionLost()
{ enable = false; allot = false; }
/// &summary&
/// 被分配出去,线程安全的
/// &/summary&
public void Repeat()
lock (this)
if (enable == false)//连接可用
throw new ResLostnExecption();//连接资源已经失效
if (allot == false)//是否可以被分配
throw new AllotExecption();//连接资源不可以被分配
if (use == true && isRepeat == false)
throw new AllotAndRepeatExecption();//连接资源已经被分配并且不允许重复引用
repeatNow++;//引用记数+1
useDegree++;//被使用次数+1
use = true;//被使用
/// &summary&
/// 被释放回来,线程安全的
/// &/summary&
public void Remove()
lock (this)
if (enable == false)//连接可用
throw new ResLostnExecption();//连接资源已经失效
if (repeatNow == 0)
throw new RepeatIsZeroExecption();//引用记数已经为0
repeatNow--;//引用记数-1
if (repeatNow == 0)
use = false;//未使用
use = true;//使用中
/// &summary&
/// 释放资源
/// &/summary&
public void Dispose()
enable = false;
connect.Close();
connect = null;
线程类为:
using System.Collections.G
using System.T
using System.D
using System.Data.SqlC
using System.T
using System.C
namespace CommonTools
/// &summary&
/// 数据库连接池,默认数据库连接方案是ODBC
/// &/summary&
public class ConnectionPool : IDisposable
#region 变量定义
private int _realFormP//连接池中存在的实际连接数(包含失效的连接)
private int _potentRealFormP//连接池中存在的实际连接数(有效的实际连接)
private int _spareRealFormP//空闲的实际连接
private int _useRealFormP//已分配的实际连接
private int _readOnlyFormP//连接池已经分配多少只读连接
private int _useFormP//已经分配出去的连接数
private int _spareFormP//目前可以提供的连接数
private int _maxC//最大连接数,最大可以创建的连接数目
private int _minC//最小连接数
private int _seepC//每次创建连接的连接数
private int _keepRealC//保留的实际空闲连接,以攻可能出现的ReadOnly使用,当空闲连接不足该数值时,连接池将创建seepConnection个连接
private int _exist = 20;//每个连接生存期限 20分钟
private int _maxRepeatDegree = 5;//可以被重复使用次数(引用记数),当连接被重复分配该值所表示的次数时,该连接将不能被分配出去
//当连接池的连接被分配尽时,连接池会在已经分配出去的连接中,重复分配连接(引用记数)。来缓解连接池压力
private DateTime _startT//服务启动时间
private string _connString = null;//连接字符串
private ConnTypeEnum _connT//连接池连接类型
private PoolState _//连接池状态
//内部对象
private List&ConnStruct& al_All = new List&ConnStruct&();//实际连接
private Hashtable hs_UseConn = new Hashtable();//正在使用的连接
private System.Timers.T//监视器记时器
private Thread threadC//创建线程
private bool isThreadCheckRun = false;
//private Mutex mUnique = new Mutex();
#endregion
//--------------------------------------------------------------------
#region 构造方法 与 初始化函数
/// &summary&
/// 初始化连接池
/// &/summary&
/// &param name="connectionString"&数据库连接字符串&/param&
public ConnectionPool(string connectionString)
{ InitConnectionPool(connectionString, ConnTypeEnum.Odbc, 200, 30, 10, 5, 5); }
/// &summary&
/// 初始化连接池
/// &/summary&
/// &param name="connectionString"&数据库连接字符串&/param&
/// &param name="cte"&数据库连接类型&/param&
public ConnectionPool(string connectionString, ConnTypeEnum cte)
{ InitConnectionPool(connectionString, cte, 200, 30, 10, 5, 5); }
/// &summary&
/// 初始化连接池
/// &/summary&
/// &param name="connectionString"&数据库连接字符串&/param&
/// &param name="cte"&数据库连接类型&/param&
/// &param name="maxConnection"&最大连接数,最大可以创建的连接数目&/param&
/// &param name="minConnection"&最小连接数&/param&
public ConnectionPool(string connectionString, ConnTypeEnum cte, int maxConnection, int minConnection)
{ InitConnectionPool(connectionString, cte, maxConnection, minConnection, 10, 5, 5); }
/// &summary&
/// 初始化连接池
/// &/summary&
/// &param name="connectionString"&数据库连接字符串&/param&
/// &param name="cte"&数据库连接类型&/param&
/// &param name="maxConnection"&最大连接数,最大可以创建的连接数目&/param&
/// &param name="minConnection"&最小连接数&/param&
/// &param name="seepConnection"&每次创建连接的连接数&/param&
/// &param name="keepConnection"&保留连接数,当空闲连接不足该数值时,连接池将创建seepConnection个连接&/param&
public ConnectionPool(string connectionString, ConnTypeEnum cte, int maxConnection, int minConnection, int seepConnection, int keepConnection)
{ InitConnectionPool(connectionString, cte, maxConnection, minConnection, seepConnection, keepConnection, 5); }
/// &summary&
/// 初始化连接池
/// &/summary&
/// &param name="connectionString"&数据库连接字符串&/param&
/// &param name="cte"&数据库连接类型&/param&
/// &param name="maxConnection"&最大连接数,最大可以创建的连接数目&/param&
/// &param name="minConnection"&最小连接数&/param&
/// &param name="seepConnection"&每次创建连接的连接数&/param&
/// &param name="keepConnection"&保留连接数,当空闲连接不足该数值时,连接池将创建seepConnection个连接&/param&
/// &param name="keepRealConnection"&当空闲的实际连接不足该值时创建连接,直到达到最大连接数&/param&
public ConnectionPool(string connectionString, ConnTypeEnum cte, int maxConnection, int minConnection, int seepConnection, int keepConnection, int keepRealConnection)
{ InitConnectionPool(connectionString, cte, maxConnection, minConnection, seepConnection, keepConnection, keepRealConnection); }
/// &summary&
/// 初始化函数
/// &/summary&
protected void InitConnectionPool(string connectionString, ConnTypeEnum cte, int maxConnection, int minConnection, int seepConnection, int keepConnection, int keepRealConnection)
if (cte == ConnTypeEnum.None)
throw new ConnTypeExecption();//参数不能是None
_ps = PoolState.UnI
this._connString = connectionS
this._connType =
this._minConnection = minC
this._seepConnection = seepC
this._keepRealConnection = keepRealC
this._maxConnection = maxC
this.time = new System.Timers.Timer(500);
this.time.Stop();
this.time.Elapsed += new System.Timers.ElapsedEventHandler(time_Elapsed);//检查事件
this.threadCreate = new Thread(new ThreadStart(createThreadProcess));//创建连接线程
#endregion
//--------------------------------------------------------------------
#region 属性部分
/// &summary&
/// 连接池服务状态
/// &/summary&
public PoolState State
{ get { return _ } }
/// &summary&
/// 连接池是否启动,改变该属性将相当于调用StartServices或StopServices方法,注:只有连接池处于Run,Stop状态情况下才可以对此属性赋值
/// &/summary&
public bool Enable
if (_ps == PoolState.Run)
return true;
return false;
if (_ps == PoolState.Run || _ps == PoolState.Stop)
if (value == true)
StartServices();
StopServices();
throw new SetValueExecption();//只有连接池处于Run,Stop状态情况下才可以对此属性赋值
/// &summary&
/// 得到或设置连接类型
/// &/summary&
public ConnTypeEnum ConnectionType
get { return _connT }
if (_ps == PoolState.Stop)
_connType =
throw new SetValueExecption();//只有在Stop状态时才可操作
/// &summary&
/// 连接池使用的连接字符串
/// &/summary&
public string ConnectionString
get { return _connS }
if (_ps == PoolState.Stop)
_connString =
throw new SetValueExecption();//只有在Stop状态时才可操作
/// &summary&
/// 得到服务器运行时间
/// &/summary&
public DateTime RunTime
if (_ps == PoolState.Stop)
return new DateTime(DateTime.Now.Ticks - _startTime.Ticks);
return new DateTime(0);
/// &summary&
/// 最小连接数
/// &/summary&
public int MinConnection
get { return _minC }
if (value & _maxConnection && value & 0 && value &= _keepRealConnection)
_minConnection =
throw new ParameterBoundExecption();//参数范围应该在 0~MaxConnection之间,并且应该大于KeepConnection
/// &summary&
/// 最大连接数,最大可以创建的连接数目
/// &/summary&
public int MaxConnection
get { return _maxC }
if (value &= _minConnection && value & 0)
_maxConnection =
throw new ParameterBoundExecption();//参数范围错误,参数应该大于minConnection
/// &summary&
/// 每次创建连接的连接数
/// &/summary&
public int SeepConnection
get { return _seepC }
if (value & 0 && value & _maxConnection)
_seepConnection =
throw new ParameterBoundExecption();//创建连接的步长应大于0,同时小于MaxConnection
/// &summary&
/// 保留的实际空闲连接,以攻可能出现的ReadOnly使用
/// &/summary&
public int KeepRealConnection
get { return _keepRealC }
if (value &= 0 && value & _maxConnection)
_keepRealConnection =
throw new ParameterBoundExecption();//保留连接数应大于等于0,同时小于MaxConnection
/// &summary&
/// 自动清理连接池的时间间隔
/// &/summary&
public double Interval
get { return time.I }
set { time.Interval = }
/// &summary&
/// 每个连接生存期限(单位分钟),默认20分钟
/// &/summary&
public int Exist
get { return _ }
if (_ps == PoolState.Stop)
throw new PoolNotStopException();//只有在Stop状态下才可以操作
/// &summary&
/// 可以被重复使用次数(引用记数)当连接被重复分配该值所表示的次数时,该连接将不能被分配出去。
/// 当连接池的连接被分配尽时,连接池会在已经分配出去的连接中,重复分配连接(引用记数)。来缓解连接池压力
/// &/summary&
public int MaxRepeatDegree
get { return _maxRepeatD }
if (value &= 0)
_maxRepeatDegree =
throw new ParameterBoundExecption();//重复引用次数应大于等于0
/// &summary&
/// 连接池最多可以提供多少个连接
/// &/summary&
public int MaxConnectionFormPool
{ get { return _maxConnection * _maxRepeatD } }
/// &summary&
/// 连接池中存在的实际连接数(有效的实际连接)
/// &/summary&
public int PotentRealFormPool
if (_ps == PoolState.Run)
return _potentRealFormP
throw new PoolNotRunException();//连接池处在非运行中
/// &summary&
/// 连接池中存在的实际连接数(包含失效的连接)
/// &/summary&
public int RealFormPool
if (_ps == PoolState.Run)
return _realFormP
throw new PoolNotRunException();//连接池处在非运行中
/// &summary&
/// 空闲的实际连接
/// &/summary&
public int SpareRealFormPool
if (_ps == PoolState.Run)
return _spareRealFormP
throw new PoolNotRunException();//连接池处在非运行中
/// &summary&
/// 已分配的实际连接
/// &/summary&
public int UseRealFormPool
if (_ps == PoolState.Run)
return _useRealFormP
throw new PoolNotRunException();//连接池处在非运行中
/// &summary&
/// 连接池已经分配多少只读连接
/// &/summary&
public int ReadOnlyFormPool
if (_ps == PoolState.Run)
return _readOnlyFormP
throw new PoolNotRunException();//连接池处在非运行中
/// &summary&
/// 已经分配的连接数
/// &/summary&
public int UseFormPool
if (_ps == PoolState.Run)
return _useFormP
throw new PoolNotRunException();//连接池处在非运行中
/// &summary&
/// 目前可以提供的连接数
/// &/summary&
public int SpareFormPool
if (_ps == PoolState.Run)
return _spareFormP
throw new PoolNotRunException();//连接池处在非运行中
#endregion
//--------------------------------------------------------------------
#region 启动服务 与 终止服务
/// &summary&
/// 启动服务,线程安全,同步调用
/// &/summary&
public void StartServices()
{ StartServices(false); }
/// &summary&
/// 启动服务,线程安全
/// &/summary&
/// &param name="ansy"&是否异步调用True为是,异步调用指,用户调用该方法后,无须等待创建结束就可继续做其他操作&/param&
public void StartServices(bool ansy)
lock (this)
createThreadMode = 0;//工作模式0
createThreadProcessRun = true;
createThreadProcessTemp = _minC
if (_ps == PoolState.UnInitialize)
threadCreate.Start();
else if (_ps == PoolState.Stop)
threadCreate.Interrupt();
throw new PoolNotStopException();//服务已经运行或者未完全结束
time.Start();
if (!ansy)
while (threadCreate.ThreadState != ThreadState.WaitSleepJoin) { Thread.Sleep(50); }//等待可能存在的创建线程结束
/// &summary&
/// 停止服务,线程安全
/// &/summary&
public void StopServices()
{ StopServices(false); }
/// &summary&
/// 停止服务,线程安全
/// &param name="needs"&是否必须退出;如果指定为false与StartServices()功能相同,如果指定为true。将未收回的连接资源关闭,这将是危险的。认为可能你的程序正在使用此资源。&/param&
/// &/summary&
public void StopServices(bool needs)
lock (this)
if (_ps == PoolState.Run)
lock (hs_UseConn)
if (needs == true)//必须退出
hs_UseConn.Clear();
if (hs_UseConn.Count != 0)
throw new ResCallBackException();//连接池资源未全部回收
time.Stop();
while (isThreadCheckRun) { Thread.Sleep(50); }//等待timer事件结束
createThreadProcessRun = false;
while (threadCreate.ThreadState != ThreadState.WaitSleepJoin) { Thread.Sleep(50); }//等待可能存在的创建线程结束
lock (al_All)
for (int i = 0; i & al_All.C i++)
al_All[i].Dispose();
al_All.Clear();
_ps = PoolState.S
throw new PoolNotRunException();//服务未启动
UpdateAttribute();//更新属性
public void Dispose()
this.StopServices();
threadCreate.Abort();
catch (Exception e) { }
#endregion
//--------------------------------------------------------------------
#region 获得连接 与 释放连接
/// &summary&
/// 在连接池中申请一个连接,使用None级别,线程安全
/// &/summary&
/// &param name="gui"&发起者&/param&
/// &returns&返回申请到的连接&/returns&
public DbConnection GetConnectionFormPool(object key)
{ return GetConnectionFormPool(key, ConnLevel.None); }
/// &summary&
/// 在连接池中申请一个连接,线程安全
/// &/summary&
/// &param name="key"&申请者&/param&
/// &param name="cl"&申请的连接级别&/param&
/// &returns&返回申请到的连接&/returns&
public DbConnection GetConnectionFormPool(object key, ConnLevel cl)
lock (this)
if (_ps != PoolState.Run)
throw new StateException();//服务状态错误
if (hs_UseConn.Count == MaxConnectionFormPool)
throw new PoolFullException();//连接池已经饱和,不能提供连接
if (hs_UseConn.ContainsKey(key))
throw new KeyExecption();//一个key对象只能申请一个连接
if (cl == ConnLevel.ReadOnly)
return GetConnectionFormPool_ReadOnly(key);//ReadOnly级别
else if (cl == ConnLevel.High)
return GetConnectionFormPool_High(key);//High级别
else if (cl == ConnLevel.None)
return GetConnectionFormPool_None(key);//None级别
return GetConnectionFormPool_Bottom(key);//Bottom级别
/// &summary&
/// 申请一个连接资源,只读方式,线程安全
/// &/summary&
/// &param name="key"&申请者&/param&
/// &returns&申请到的连接对象&/returns&
protected DbConnection GetConnectionFormPool_ReadOnly(object key)
ConnStruct cs = null;
for (int i = 0; i & al_All.C i++)
cs = al_All[i];
if (cs.Enable == false || cs.Allot == false || cs.UseDegree == _maxRepeatDegree || cs.IsUse == true)
return GetConnectionFormPool_Return(key, cs, ConnLevel.ReadOnly); //返回得到的连接
return GetConnectionFormPool_Return(key, null, ConnLevel.ReadOnly);
/// &summary&
/// 申请一个连接资源,优先级-高,线程安全
/// &/summary&
/// &param name="key"&申请者&/param&
/// &returns&申请到的连接对象&/returns&
protected DbConnection GetConnectionFormPool_High(object key)
ConnStruct cs = null;
ConnStruct csTemp = null;
for (int i = 0; i & al_All.C i++)
csTemp = al_All[i];
if (csTemp.Enable == false || csTemp.Allot == false || csTemp.UseDegree == _maxRepeatDegree)//不可以分配跳出本次循环。
csTemp = null;
if (csTemp.UseDegree == 0)//得到最合适的
else//不是最合适的放置到最佳选择中
if (cs != null)
if (csTemp.UseDegree & cs.UseDegree)
//与上一个最佳选择选出一个最佳的放置到cs中
return GetConnectionFormPool_Return(key, cs, ConnLevel.High);//返回最合适的连接
/// &summary&
/// 申请一个连接资源,优先级-中,线程安全
/// &/summary&
/// &param name="key"&申请者&/param&
/// &returns&申请到的连接对象&/returns&
protected DbConnection GetConnectionFormPool_None(object key)
List&ConnStruct& al = new List&ConnStruct&();
ConnStruct cs = null;
for (int i = 0; i & al_All.C i++)
cs = al_All[i];
if (cs.Enable == false || cs.Allot == false || cs.UseDegree == _maxRepeatDegree)//不可以分配跳出本次循环。
if (cs.Allot == true)
al.Add(cs);
if (al.Count == 0)
return GetConnectionFormPool_Return(key, null, ConnLevel.None);//发出异常
return GetConnectionFormPool_Return(key, (al[al.Count / 2]), ConnLevel.None);//返回连接
/// &summary&
/// 申请一个连接资源,优先级-低,线程安全
/// &/summary&
/// &param name="key"&申请者&/param&
/// &returns&申请到的连接对象&/returns&
protected DbConnection GetConnectionFormPool_Bottom(object key)
ConnStruct cs = null;
ConnStruct csTemp = null;
for (int i = 0; i & al_All.C i++)
csTemp = al_All[i];
if (csTemp.Enable == false || csTemp.Allot == false || csTemp.UseDegree == _maxRepeatDegree)//不可以分配跳出本次循环。
csTemp = null;
else//不是最合适的放置到最佳选择中
if (cs != null)
if (csTemp.UseDegree & cs.UseDegree)
//与上一个最佳选择选出一个最佳的放置到cs中
return GetConnectionFormPool_Return(key, cs, ConnLevel.Bottom);//返回最合适的连接
/// &summary&
/// 返回DbConnection对象,同时做获得连接时的必要操作
/// &/summary&
/// &param name="key"&key&/param&
/// &param name="cs"&ConnStruct对象&/param&
/// &param name="cl"&级别&/param&
/// &param name="readOnly"&是否为只读属性&/param&
/// &returns&&/returns&
private DbConnection GetConnectionFormPool_Return(object key, ConnStruct cs, ConnLevel cl)
if (cs == null)
throw new Exception();
cs.Repeat();
hs_UseConn.Add(key, cs);
if (cl == ConnLevel.ReadOnly)
cs.Allot = false;
cs.IsRepeat = false;
catch (Exception e)
throw new OccasionExecption();//连接资源耗尽,或错误的访问时机。
UpdateAttribute();//更新属性
return cs.C
/// &summary&
/// 释放申请的数据库连接对象,线程安全
/// &param name="key"&key表示数据库连接申请者&/param&
/// &/summary&
public void DisposeConnection(object key)
lock (hs_UseConn)
ConnStruct cs = null;
if (_ps == PoolState.Run)
if (!hs_UseConn.ContainsKey(key))
throw new NotKeyExecption();//无法释放,不存在的key
cs = (ConnStruct)hs_UseConn[key];
cs.IsRepeat = true;
if (cs.Allot == false)
if (cs.Enable == true)
cs.Allot = true;
cs.Remove();
hs_UseConn.Remove(key);
throw new PoolNotRunException();//服务未启动
UpdateAttribute();//更新属性
#endregion
//--------------------------------------------------------------------
#region 私有方法
private int createThreadMode = 0;//创建线程工作模式
private int createThreadProcessTemp = 0;//需要创建的连接数
private bool createThreadProcessRun = false;//是否决定创建线程将继续工作,如果不继续工作则线程会将自己处于阻止状态
/// &summary&
/// 创建线程
/// &/summary&
private void createThreadProcess()
bool join = false;
int createThreadProcessTemp_inside = createThreadProcessT
_ps = PoolState.I
while (true)
join = false;
_ps = PoolState.R
if (createThreadProcessRun == false)
{//遇到终止命令
try { threadCreate.Join(); }
catch (Exception e) { }
if (createThreadMode == 0)
//------------------------begin mode
lock (al_All)//lock类似于synchronized
if (al_All.Count & createThreadProcessTemp_inside)
al_All.Add(CreateConnection(_connString, _connType));
join = true;
//------------------------end mode
else if (createThreadMode == 1)
//------------------------begin mode
lock (al_All)
if (createThreadProcessTemp_inside != 0)
createThreadProcessTemp_inside--;
al_All.Add(CreateConnection(_connString, _connType));
join = true;
//------------------------end mode
join = true;
//-------------------------------------------------------------------------
if (join == true)
UpdateAttribute();//更新属性
createThreadProcessTemp = 0;
threadCreate.Join();
catch (Exception e)
{ createThreadProcessTemp_inside = createThreadProcessT }//得到传入的变量
/// &summary&
/// 检测事件
/// &/summary&
private void time_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
ConnStruct cs = null;
time.Stop();//关闭自己
isThreadCheckRun = true;
//如果正在执行创建连接则退出
if (threadCreate.ThreadState != ThreadState.WaitSleepJoin)
//------------------------------------------------------
lock (al_All)
int n = 0;
for (int i = 0; i & al_All.C i++)
cs = al_All[i];
TestConnStruct(cs);//测试
if (cs.Enable == false && cs.RepeatNow == 0)//没有引用的失效连接
cs.Close();//关闭它
al_All.Remove(cs);//删除
//------------------------------------------------------
UpdateAttribute();//更新属性
if (_spareRealFormPool & _keepRealConnection)//保留空闲实际连接数不足
createThreadProcessTemp = GetNumOf(_realFormPool, _seepConnection, _maxConnection);
createThreadProcessTemp = 0;
//if (createThreadProcessTemp != 0)
Console.WriteLine("创建" + createThreadProcessTemp);
if (createThreadProcessTemp != 0)
//启动创建线程,工作模式1
createThreadMode = 1;
threadCreate.Interrupt();
isThreadCheckRun = false;
time.Start();//打开自己
/// &summary&
/// 得到当前要增加的量
/// &/summary&
private int GetNumOf(int nowNum, int seepNum, int maxNum)
if (maxNum &= nowNum + seepNum)
return seepN
return maxNum - nowN
/// &summary&
/// 用指定类型创建连接
/// &/summary&
/// &param name="conn"&连接字符串&/param&
/// &param name="cte"&连接类型&/param&
/// &param name="dt"&连接超时时间&/param&
/// &returns&返回创建的连接&/returns&
private ConnStruct CreateConnection(string conn, ConnTypeEnum cte)
DbConnection db = null;
if (cte == ConnTypeEnum.Odbc)
db = new System.Data.Odbc.OdbcConnection(conn);//ODBC数据源连接
else if (cte == ConnTypeEnum.OleDb)
db = new System.Data.OleDb.OleDbConnection(conn);//OLE DB数据连接
else if (cte == ConnTypeEnum.SqlClient)
db = new System.Data.SqlClient.SqlConnection(conn);//SqlServer数据库连接
ConnStruct cs = new ConnStruct(db, cte, DateTime.Now);
cs.Open();
/// &summary&
/// 测试ConnStruct是否过期
/// &/summary&
/// &param name="cs"&被测试的ConnStruct&/param&
private void TestConnStruct(ConnStruct cs)
//此次被分配出去的连接是否在此次之后失效
if (cs.UseDegree == _maxRepeatDegree)
cs.SetConnectionLost();//超过使用次数
if (cs.CreateTime.AddMinutes(_exist).Ticks &= DateTime.Now.Ticks)
cs.SetConnectionLost();//连接超时
if (cs.Connection.State == ConnectionState.Closed)
cs.SetConnectionLost();//连接被关闭
/// &summary&
/// 更新属性
/// &/summary&
private void UpdateAttribute()
int temp_readOnlyFormPool = 0;//连接池已经分配多少只读连接
int temp_potentRealFormPool = 0;//连接池中存在的实际连接数(有效的实际连接)
int temp_spareRealFormPool = 0;//空闲的实际连接
int temp_useRealFormPool = 0;//已分配的实际连接
int temp_spareFormPool = MaxConnectionFormP//目前可以提供的连接数
//---------------------------------
lock (hs_UseConn)
_useFormPool = hs_UseConn.C
//---------------------------------
ConnStruct cs = null;
int n = 0;
lock (al_All)
_realFormPool = al_All.C
for (int i = 0; i & al_All.C i++)
cs = al_All[i];
if (cs.Allot == false && cs.IsUse == true && cs.IsRepeat == false)
temp_readOnlyFormPool++;
//有效的实际连接
if (cs.Enable == true)
temp_potentRealFormPool++;
//空闲的实际连接
if (cs.Enable == true && cs.IsUse == false)
temp_spareRealFormPool++;
//已分配的实际连接
if (cs.IsUse == true)
temp_useRealFormPool++;
//目前可以提供的连接数
if (cs.Allot == true)
temp_spareFormPool = temp_spareFormPool - cs.RepeatN
temp_spareFormPool = temp_spareFormPool - _maxRepeatD
_readOnlyFormPool = temp_readOnlyFormP
_potentRealFormPool = temp_potentRealFormP
_spareRealFormPool = temp_spareRealFormP
_useRealFormPool = temp_useRealFormP
_spareFormPool = temp_spareFormP
#endregion
自定义异常类:
namespace CommonTools
/// &summary&
/// 服务未启动
/// &/summary&
public class PoolNotRunException : Exception
public PoolNotRunException() : base("服务未启动") { }
public PoolNotRunException(string message) : base(message) { }
/// &summary&
/// 服务已经运行或者未完全结束
/// &/summary&
public class PoolNotStopException : Exception
public PoolNotStopException() : base("服务已经运行或者未完全结束") { }
public PoolNotStopException(string message) : base(message) { }
/// &summary&
/// 连接池资源未全部回收
/// &/summary&
public class ResCallBackException : Exception
public ResCallBackException() : base("连接池资源未全部回收") { }
public ResCallBackException(string message) : base(message) { }
/// &summary&
/// 连接池已经饱和,不能提供连接
/// &/summary&
public class PoolFullException : Exception
public PoolFullException() : base("连接池已经饱和,不能提供连接") { }
public PoolFullException(string message) : base(message) { }
/// &summary&
/// 服务状态错误
/// &/summary&
public class StateException : Exception
public StateException() : base("服务状态错误") { }
public StateException(string message) : base(message) { }
/// &summary&
/// 一个key对象只能申请一个连接
/// &/summary&
public class KeyExecption : Exception
public KeyExecption() : base("一个key对象只能申请一个连接") { }
public KeyExecption(string message) : base(message) { }
/// &summary&
/// 无法释放,不存在的key
/// &/summary&
public class NotKeyExecption : Exception
public NotKeyExecption() : base("无法释放,不存在的key") { }
public NotKeyExecption(string message) : base(message) { }
/// &summary&
/// 当前连接池状态不可以对属性赋值
/// &/summary&
public class SetValueExecption : Exception
public SetValueExecption() : base("当前连接池状态不可以对属性赋值") { }
public SetValueExecption(string message) : base(message) { }
/// &summary&
/// 参数范围错误
/// &/summary&
public class ParameterBoundExecption : Exception
public ParameterBoundExecption() : base("参数范围错误") { }
public ParameterBoundExecption(string message) : base(message) { }
/// &summary&
/// 无效的ConnTypeEnum类型参数
/// &/summary&
public class ConnTypeExecption : Exception
public ConnTypeExecption() : base("无效的ConnTypeEnum类型参数") { }
public ConnTypeExecption(string message) : base(message) { }
/// &summary&
/// 连接资源耗尽,或错误的访问时机。
/// &/summary&
public class OccasionExecption : Exception
public OccasionExecption() : base("连接资源耗尽,或错误的访问时机。") { }
public OccasionExecption(string message) : base(message) { }
/// &summary&
/// 连接资源已经失效。
/// &/summary&
public class ResLostnExecption : Exception
public ResLostnExecption() : base("连接资源已经失效。") { }
public ResLostnExecption(string message) : base(message) { }
/// &summary&
/// 连接资源不可以被分配。
/// &/summary&
public class AllotExecption : Exception
public AllotExecption() : base("连接资源不可以被分配。") { }
public AllotExecption(string message) : base(message) { }
/// &summary&
/// 连接资源已经被分配并且不允许重复引用。
/// &/summary&
public class AllotAndRepeatExecption : AllotExecption
public AllotAndRepeatExecption() : base("连接资源已经被分配并且不允许重复引用") { }
public AllotAndRepeatExecption(string message) : base(message) { }
/// &summary&
/// 引用记数已经为0。
/// &/summary&
public class RepeatIsZeroExecption : Exception
public RepeatIsZeroExecption() : base("引用记数已经为0。") { }
public RepeatIsZeroExecption(string message) : base(message) { }
&Java代码:
import dateBaseConnectionPool.*;
import dateBaseConnectionPool.poolException.*;
import java.sql.C
public class AppRun {
public static void main(String[] args) {
ConnectionPool c = new ConnectionPool() {
protected Connection CreateConnection(String connString,
String driveString, String userID, String password)
throws CreateConnectionException {
Class.forName(driveString);
Connection con = java.sql.DriverManager.getConnection( connString, userID, password);
} catch (Exception e) {
throw new CreateConnectionException();
c.set_String(
"jdbc:sqlserver://127.0.0.1:1433;DatabaseName=TestDemo",
"com.microsoft.sqlserver.jdbc.SQLServerDriver");
c.set_DataBaseUser("sa", "qs@123456");
c.set_KeepRealConnection(2);
c.set_MinConnection(3);
c.set_MaxConnection(10);
c.set_MaxRepeatDegree(2);
c.set_SeepConnection(3);
c.StartServices();
} catch (PoolNotStopException ex1) {
Pool p = new Pool();
p.start();
Thread.currentThread().sleep(5000);
c.Dispose();
} catch (Exception e) {
class Pool extends Thread {
public ConnectionP
public void run() {
while (true) {
c.GetConnectionFormPool(new Object(),
ConnectionPool.ConnLevel_Bottom);
Thread.sleep(2000);
System.out.println("实际连接(包含失效的):" + c.get_RealFormPool());
System.out
.println("实际连接(不包含失效的):" + c.get_PotentRealFormPool());
System.out.println("目前可以提供的连接数:" + c.get_SpareFormPool());
System.out.println("空闲的实际连接:" + c.get_SpareRealFormPool());
System.out.println("已分配的实际连接:" + c.get_UseRealFormPool());
System.out.println("已分配连接数:" + c.get_UseFormPool());
System.out.println("已分配只读连接:" + c.get_ReadOnlyFormPool());
System.out.println("--------------------------");
} catch (Exception ex) {
System.out.println(ex.getMessage());
package dateBaseConnectionP
import java.sql.C
import java.util.ArrayL
import java.util.H
import java.util.D
import java.util.C
import dateBaseConnectionPool.poolException.*;
public class ConnectionPool {
* &b&独占方式&/b&&br&
* 使用空闲的实际连接分配连接资源,并且在该资源释放回之前,该资源在连接池中将不能将其引用分配给其他申请者。&br&
* 如果连接池中所有实际连接资源都已经分配出去,那么即使连接池可以在分配引用资源在该模式下连接迟将不会分配连接资源,
* 连接池会产生一个异常,标志连接池资源耗尽。&br&&br&
* &font color='#006600'&例:假如一个实际连接可以被分配5次,那么使用该模式申请连接的话您将损失4个可分配的连接,只将得到一个连接资源。
* 直至该资源被释放回连接池,连接池才继续分配它剩余的4次机会。&/font&
* &br&&br&
* 当您在使用连接时可能应用到事务时,可以使用该模式的连接,以确定在事务进行期间您可以对该连接具有独享权限,以避免各个数据库操作访问的干扰。
public static final int ConnLevel_ReadOnly = 10;
* &b&优先级-高&/b&&br&
* 使用空闲的实际连接分配连接资源,并且在该资源释放回之前,该资源在连接池中将可能将其引用分配给其他申请者。&br&
* &font color='#FF0000'&*注意:此级别不保证在分配该资源后,仍然保持独立占有连接资源,若想独立占有资源请使用ReadOnely,
* 因为当连接池达到某一时机时该资源将被重复分配(引用记数)然而这个时机是不可预测的。&/font&&br&
* 如果您申请的连接会用于事务处理您可以使用&font color='#0033CC'&ConnLevel_ReadOnly&/font&级别
public static final int ConnLevel_High = 11;
* &b&优先级-中&/b&&br&
* 适当应用引用记数技术分配连接资源。&br&
* 在该模式下,连接池内部会按照实际连接已经使用次数排序(多-&少),然后在结果中选取 1/3 位置的连接资源返回。&br&
* 与优先级-高相同该模式也不具备保持独立占有连接资源的特性。&br&
* 如果您申请的连接会用于事务处理您可以使用&font color='#0033CC'&ConnLevel_ReadOnly&/font&级别
public static final int ConnLevel_None = 12;
* &b&优先级-底&/b&&br&
* 尽可能使用引用记数技术分配连接。&br&
* 在该模式下,连接池内部会按照实际连接已经使用次数排序(多-&少),然后在结果中选取被使用最多的返回。&br&
* 该模式适合处理较为不重要的连接资源请求。&br&
* 与优先级-高相同该模式也不具备保持独立占有连接资源的特性。&br&
* 如果您申请的连接会用于事务处理您可以使用&font color='#0033CC'&ConnLevel_ReadOnly&/font&级别
public static final int ConnLevel_Bottom = 13;
* 表示未对连接池未被调用过StartSeivice方法。
public static final int PoolState_UnInitialize = 20;
* 连接池初始化中,该状态下服务正在按照参数初始化连接池。StopServices之后将首先跳转到该状态
public static final int PoolState_Initialize = 21;
* 当连接池开始运做时则表示为该状态
public static final int PoolState_Run = 22;
* 连接池被调用StopServices停止状态
public static final int PoolState_Stop = 23;
private int _RealFormP //连接池中存在的实际连接数(包含失效的连接)
private int _PotentRealFormP //连接池中存在的实际连接数(有效的实际连接)
private int _SpareRealFormP //空闲的实际连接
private int _UseRealFormP //已分配的实际连接
private int _ReadOnlyFormP //连接池已经分配多少只读连接
private int _UseFormP //已经分配出去的连接数
private int _SpareFormP //目前可以提供的连接数
private int _MaxC //最大连接数,最大可以创建的连接数目
private int _MinC //最小连接数
private int _SeepC //每次创建连接的连接数
private int _KeepRealC //保留的实际空闲连接,以攻可能出现的ReadOnly使用,当空闲连接不足该数值时,连接池将创建seepConnection个连接
private int _Exist = 20; //每个连接生存期限 20分钟
private String _userID="";
private String _password="";
//可以被重复使用次数(引用记数),当连接被重复分配该值所表示的次数时,该连接将不能被分配出去
//当连接池的连接被分配尽时,连接池会在已经分配出去的连接中,重复分配连接(引用记数)。来缓解连接池压力
private int _MaxRepeatDegree = 5;
private Date _StartT //服务启动时间
private String _ConnString = null; //连接字符串
private String _DriveString = null; //驱动字符串
private int _PoolS //连接池状态
//内部对象
private ArrayList&ConnStruct& al_All = new ArrayList&ConnStruct&(); //实际连接
private Hashtable&Object, ConnStruct& hs_UseConn = new Hashtable&Object, ConnStruct&(); //正在使用的连接
private CreateThreadProcess threadC
private CheckThreadProcess threadC
//-------------------------------------------------------------------------------------------
* 初始化连接池
public ConnectionPool() {
InitConnectionPool("", "", 200, 30, 10, 5);
* 初始化连接池
* @param connectionString String 数据库连接字符串。
* @param driveString String 数据库驱动字符串。
public ConnectionPool(String connectionString, String driveString) {
InitConnectionPool(connectionString, driveString, 200, 30, 10, 5);
* 初始化连接池
* @param connectionString String 数据库连接字符串。
* @param driveString String 数据库驱动字符串。
* @param maxConnection int 最大实际连接数,最大可以创建的连接数目。
* @param minConnection int 最小实际连接数。
public ConnectionPool(String connectionString, String driveString, int maxConnection, int minConnection) {
InitConnectionPool(connectionString, driveString, maxConnection, minConnection, 10, 5);
* 初始化连接池
* @param connectionString String 数据库连接字符串。
* @param driveString String 数据库驱动字符串。
* @param maxConnection int 最大实际连接数,最大可以创建的连接数目。
* @param minConnection int 最小实际连接数。
* @param seepConnection int 每次创建连接的连接数。当空闲的实际连接不足该值时创建连接,直到达到最大连接数
* @param keepRealConnection int 保留连接数,当空闲连接不足该数值时,连接池将创建seepConnection个连接。
public ConnectionPool(String connectionString, String driveString, int maxConnection, int minConnection, int seepConnection, int keepRealConnection) {
InitConnectionPool(connectionString, driveString, maxConnection, minConnection, seepConnection, keepRealConnection);
* 初始化连接池
* @param connectionString String 数据库连接字符串。
* @param driveString String 数据库驱动字符串。
* @param maxConnection int 最大实际连接数,最大可以创建的连接数目。
* @param minConnection int 最小实际连接数。
* @param seepConnection int 每次创建连接的连接数。当空闲的实际连接不足该值时创建连接,直到达到最大连接数
* @param keepRealConnection int 保留连接数,当空闲连接不足该数值时,连接池将创建seepConnection个连接。
private void InitConnectionPool(String connectionString, String driveString, int maxConnection, int minConnection, int seepConnection, int keepRealConnection) {
this._PoolState = PoolState_UnI
this._ConnString = connectionS
this._DriveString = driveS
this._MinConnection = minC
this._SeepConnection = seepC
this._KeepRealConnection = keepRealC
this._MaxConnection = maxC
this.threadCheck = new CheckThreadProcess();
this.threadCheck.setDaemon(true);
this.threadCreate = new CreateThreadProcess();
this.threadCreate.setDaemon(true);
this.threadCheck.start();
while(threadCheck.getState()!= Thread.State.WAITING){}
//-------------------------------------------------------------------------------------------
* &p&创建线程类&/p&
private class CreateThreadProcess extends Thread {
public int createThreadMode = 0; //创建线程工作模式
public int createThreadProcessTemp = 0; //需要创建的连接数
public boolean createThreadProcessRun = false; //是否决定创建线程将继续工作,如果不继续工作则线程会将自己处于阻止状态
public void run() {
boolean join = false;
int createThreadProcessTemp_inside = createThreadProcessT
_PoolState = PoolState_I
while (true)
join = false;
_PoolState = PoolState_R
if (createThreadProcessRun == false)
{//遇到终止命令
this.join();//中断自己
} catch (Exception e) {/* */}
if (createThreadMode == 0)
//------------------------begin mode
synchronized (al_All)
if (al_All.size() & createThreadProcessTemp_inside)
al_All.add(CreateConnectionTemp(_ConnString,_DriveString,_userID,_password));
join = true;
//------------------------end mode
else if (createThreadMode == 1)
//------------------------begin mode
synchronized (al_All)
if (createThreadProcessTemp_inside != 0)
createThreadProcessTemp_inside--;
al_All.add(CreateConnectionTemp(_ConnString,_DriveString,_userID,_password));
join = true;
//------------------------end mode
join = true;
//-------------------------------------------------------------------------
if (join == true)
UpdateAttribute();//更新属性
createThreadProcessTemp = 0;
this.join(); //中断自己
} catch (Exception e) {
createThreadProcessTemp_inside = createThreadProcessT
} //得到传入的变量
* &p&检测事件&/p&
private class CheckThreadProcess extends Thread {
private long _Interval = 100; //执行间隔
private boolean timeSize=false;
* 启动记时器
public void StartTimer()
timeSize=true;
if (this.getState()==Thread.State.NEW)
this.start();
else if (this.getState()==Thread.State.WAITING)
this.interrupt();
* 停止记时器
public void StopTimer()
timeSize=false;
while(this.getState()!=Thread.State.WAITING){/**/}
public void aRun()
ConnStruct cs = null;
//如果正在执行创建连接则退出
if (threadCreate.getState() != Thread.State.WAITING)
//------------------------------------------------------
synchronized (al_All)
for (int i = 0; i & al_All.size(); i++)
cs = al_All.get(i);
TestConnStruct(cs);//测试
if (cs.GetEnable() == false && cs.GetRepeatNow() == 0)//没有引用的失效连接
cs.Close();//关闭它
al_All.remove(cs);//删除
//------------------------------------------------------
UpdateAttribute();//更新属性
if (_SpareRealFormPool & _KeepRealConnection)//保留空闲实际连接数不足
threadCreate.createThreadProcessTemp = GetNumOf(_RealFormPool, _SeepConnection, _MaxConnection);
threadCreate.createThreadProcessTemp = 0;
//if (threadCreate.createThreadProcessTemp != 0)
System.out.println("创建" + threadCreate.createThreadProcessTemp);
System.out.println(threadCreate.getState()+ " this " + this.getState());
if (threadCreate.createThreadProcessTemp != 0)
//启动创建线程,工作模式1
threadCreate.createThreadMode = 1;
threadCreate.interrupt();
public void run() {
while (true) {
this.join(_Interval);
if (timeSize == true)
this.join();
} catch (InterruptedException ex1) {/**/ }
* 设置执行时间间隔
* @param value double 时间间隔
public void setInterval(long value) {
_Interval =
* 获得执行时间间隔
* @return double 时间间隔
public long getInterval() {
* 得到当前要增加的量
* @param nowNum int 当前值
* @param seepNum int 步长
* @param maxNum int 最大值
* @return int 当前要增加的量
private int GetNumOf(int nowNum, int seepNum, int maxNum) {
if (maxNum &= nowNum + seepNum)
return seepN
return maxNum - nowN
//-------------------------------------------------------------------------------------------
* 设置连接池字符串
* @param _ConnString String 连接字符串
* @param _DriveString String 驱动字符串
* @throws StateException 服务状态错误
public void set_String(String _ConnString, String _DriveString) throws StateException {
if (_ConnString != null && _DriveString != null &&
(_PoolState == PoolState_UnInitialize || _PoolState == PoolState_Stop)) {
this._ConnString = _ConnS
this._DriveString = _DriveS
throw new StateException(); //服务状态错误
* 设置每个连接生存期限(单位分钟),默认20分钟
* @param _Exist int 连接生存期限
* @throws StateException 服务状态错误
public void set_Exist(int _Exist) throws StateException {
if (_PoolState == PoolState_Stop) {
this._Exist = _E
throw new StateException(); //服务状态错误
* 设置最小实际连接数
* @param _MinConnection int 最小实际连接数
* @throws ParameterBoundExecption 参数范围应该在 0~MaxConnection之间,并且应该大于KeepConnection
public void set_MinConnection(int _MinConnection) throws ParameterBoundException {
if (_MinConnection & _MaxConnection && _MinConnection & 0 && _MinConnection &= _KeepRealConnection)
this._MinConnection = _MinC
throw new ParameterBoundException(); //参数范围应该在 0~MaxConnection之间,并且应该大于KeepConnection
* 可以被重复使用次数(引用记数)当连接被重复分配该值所表示的次数时,该连接将不能被分配出去。
* 当连接池的连接被分配尽时,连接池会在已经分配出去的连接中,重复分配连接(引用记数)。来缓解连接池压力
* @param _MaxRepeatDegree int 引用记数
* @throws ParameterBoundExecption 重复引用次数应大于0
public void set_MaxRepeatDegree(int _MaxRepeatDegree) throws ParameterBoundException {
if (_MaxRepeatDegree & 0)
this._MaxRepeatDegree = _MaxRepeatD
throw new ParameterBoundException(); //重复引用次数应大于0
* 设置最大可以创建的实际连接数目
* @param _MaxConnection int 最大可以创建的实际连接数目
* @throws ParameterBoundExecption 参数范围错误,参数应该大于MinConnection
public void set_MaxConnection(int _MaxConnection) throws ParameterBoundException {
if (_MaxConn}

我要回帖

更多关于 场景 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信