【虎.无名】看了
Roson的db4o连接池实现,似乎存在一些问题:
1,使用sleep或者wait/notify是为了避免循环忙等待,这个非常消耗CPU资源,否则不适合用于生产环境。
2,限制在Jdk1.5以上版本了,并非必要。
3,用户应该可以选择本地模式,还是远程模式;对于后者,需要远程服务器和端口,同时,在代码上,就无需Db4o.openServer了。
于是乎,一时手痒,就重新实现了一个,看看测试效果,虽然达到了互斥,但是db4o内部似乎还存在一些问题。set进去的类,没有成功保存,奇怪中。
/**
* Created on 2006-11-24
* @author liusheng (nike.lius@gmail.com)
* @function 针对db4o的连接池管理,
* @link file:///D:/OSS/db4o-5.5/doc/tutorial/index.html
* DONE 参考了Rosen的ConnectionPool实现,并加以改进,Blog主页如下;
* @link http://www.blogjava.net/rosen/category/13739.html
* DONE 采用setter依赖注入方式,兼容Spring框架;
* DONE 完成Poll拉模式连接池;db4o_pool中只存放空闲连接;
* DONE 在main()中使用多线程测试,
* TODO 在多线程中,set()后无效,已经commit了,奇怪。
*/
public class Db4oPool implements Db4oPoolInf {
protected static Log _log = LogFactory.getLog(Db4oPool.class);
//-------------------------------------
private int _minSize = 1; //允许的空闲连接;
private int _maxSize = 2;
public void setMinSize(int n) { _minSize = n; }
public void setMaxSize(int n) { _maxSize = n; }
public int getMinSize() { return _minSize; }
public int getMaxSize() { return _maxSize; }
private String _file = null;
private String _host = null;
private int _port = 0;
private String _usr = null;
private String _pwd = null;
public void set_file(String file) { _file = file; }
public void set_host(String host) { _host = host; }
public void set_port(int port) { _port = port; }
public void set_usr(String s) { _usr = s; }
public void set_pwd(String s) { _pwd = s; }
//-------------------------------------
private ObjectServer db4o_server = null; //only for local
private List db4o_pool = null; //只存放空闲连接
private String db4o_mode = null;
private int db4o_count = 0; //当前连接数
//-------------------------------------
public Db4oPool() {} //需要调用set方法;
public Db4oPool(String file) {
set_file(file); //Embedded模式
db4o_mode = "embedded";
}
public Db4oPool(String host, int port, String usr, String pwd) {
set_host(host); //Client模式
set_port(port);
set_usr(usr);
set_pwd(pwd);
db4o_mode = "remote";
}
//-------------------------------------
public void start() throws Exception {
synchronized(this){
if (db4o_pool!=null) return;
db4o_pool = Collections.synchronizedList(new LinkedList());
if (_file!=null) { //对于embedded模式,打开本地库
db4o_server = Db4o.openServer(_file, _port);
_log.debug("# openServer("+_port+")..."+_file);
if (_port>0 && _usr!=null && _pwd!=null) {
db4o_server.grantAccess(_usr,_pwd); //授权
_log.debug("# grantAccess("+_usr+")...ok");
}
}
for(int i=0; i<this._maxSize; i++){ //打开多个数据库连接,尝试最大连接数
ObjectContainer oc = this.m_open();
db4o_pool.add(oc);
}
_log.debug("# start()...ok/"+db4o_pool.size());
}
}
public void stop() {
synchronized(this){
for(Iterator i=db4o_pool.iterator(); i.hasNext(); ) {
ObjectContainer oc = (ObjectContainer)i.next();
oc.close();
}
db4o_pool.clear();
db4o_pool = null;//全部清除
if (db4o_server!=null) {
_log.debug("* close()...server");
db4o_server.close();
db4o_server = null;
}
_log.debug("* stop()...ok/"+db4o_mode);
}
}
protected ObjectContainer m_open() throws IOException {
ObjectContainer oc = null;
if (db4o_server!=null) { //已经打开
oc = db4o_server.openClient();
db4o_count++;
}else if (_host!=null && _usr!=null && _pwd!=null) {
oc = Db4o.openClient(_host, _port, _usr, _pwd);
db4o_count++;
}else {
throw new IllegalArgumentException("need to set host,port,usr,pwd");
}
_log.debug("# m_open()..."+oc);
return oc;
}
protected void m_close(ObjectContainer oc) {
oc.close(); db4o_count--;
_log.debug("* m_close()..."+oc);
}
protected void m_commit(ObjectContainer oc) {
oc.commit(); //确保完成最后修改部分;
_log.debug("* m_commit()..."+oc);
}
//-------------------------------------
public synchronized ObjectContainer getConnection() throws Exception {
if (db4o_pool==null) {
throw new RuntimeException("(db4o_pool==null)");
}
while(db4o_pool.size()==0 && db4o_count>=_maxSize) {
_log.warn("getConnection()...wait/size=0,count="+db4o_count);
wait(1000);
}
ObjectContainer oc = null;
if (db4o_pool.size()>0) { //db4o_count<_maxSize
Object obj = db4o_pool.remove(0);
oc = (ObjectContainer)obj;
}else {
oc = m_open();
}
return oc;
}
public synchronized void closeConnection(ObjectContainer oc) {
this.m_commit(oc); //保险起见;
if (db4o_pool.size() < this._minSize) {
db4o_pool.add(oc); //添加到连接池中;
_log.debug("# closeConnection()...pooled 池化");
}else {
m_close(oc); //直接释放
_log.debug("# closeConnection()...closed 释放");
}
notify();
}
//-------------------------------------
static Random RAND = new Random(113);
static class TJob extends Thread {
Db4oPoolInf _pool = null;
public TJob(Db4oPoolInf pool) {
_pool = pool;
}
public void run() {
ObjectContainer oc = null;
try {
oc = _pool.getConnection();//释放
oc.set("Hello "+this.getName());
oc.commit(); //奇怪,没有设置进去?? # run()...q:0
ObjectSet os = oc.query(String.class);
_log.debug("# run()...q:"+os.size());
Util.sleepMSec(RAND.nextInt(500)+500); //随机等待一定时间,模拟实际操作
_log.debug("# run()...end");
}catch(Exception e){
e.printStackTrace();
}finally{
_pool.closeConnection(oc); //释放
}
}
}
public static void main(String[] args) throws IOException {
Util.configureClassPath("res/log4j.properties");
Db4oPool pool = new Db4oPool("db4o/pool/Db4oPool.yap");
try {
pool.setMinSize(3);
pool.setMaxSize(5);
pool.set_port(8888); //可选,运行外部访问;
pool.set_usr("USER"); //可选
pool.set_pwd("PASS"); //可选
pool.start();
//多线程测试
Thread[] tt = new Thread[20];
for(int i=0; i<tt.length; i++) {
tt[i] = new TJob(pool);
tt[i].start();
}
_log.debug("------- wait for join ------");
for(int i=0; i<tt.length; i++) {
tt[i].join();
}
}catch(Exception e) {
e.printStackTrace();
}finally{
pool.stop();
}
_log.debug("--------- END -------");
}
}
需要的辅助类如下,用于配置log4j以及随机等待。
class Util {
protected static Log _log = LogFactory.getLog(Util.class);
public static void configureClassPath(String cfg) throws IOException {
//格式: com/bs2/core/my.properties
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(cfg);
if (is==null) throw new IOException("Not Found in ClassPath:"+cfg);
Properties props = new Properties();
try { props.load(is); }finally{ is.close(); }
PropertyConfigurator.configure(props);
_log.debug("# configureClassPath()..."+cfg);
}
public static void sleepMSec(int msec) {
try {
_log.debug("# sleepMSec("+msec+")...");
Thread.sleep(msec);
} catch (InterruptedException e) {
// 忽略
}
}
}
分享到:
相关推荐
"db4o 使用指南" db4o 是一个开源的面向对象数据库,能够轻松地将 Java 对象持久化到数据库中。本文将详细介绍 db4o 的安装、启动、查询方式、对象持久化、数据库文件结构、主要包结构等知识点。 一、db4o 安装和...
Db4o,全称为“Database for Objects”,是一个开源的对象数据库管理系统,主要应用于Java和.NET平台。这个项目专注于提供一种简单的方式来存储和检索Java对象,无需SQL或其他中间映射层。在“Db4o的简单操作项目”...
**db4o 8.0 详解及中文指南** db4o(Database for Objects)是一款开源的对象数据库系统,它允许开发者直接将Java或.NET对象存储到数据库中,无需进行ORM(对象关系映射)。db4o的目标是简化数据管理,提供更接近...
**db4o(Database for Objects)** 是一个开源的对象数据库管理系统(Object-Relational Mapping,ORM),它允许开发者直接在Java或.NET平台上存储和检索Java对象或.NET对象,无需进行SQL查询或者映射过程。db4o的...
### db4o-7.12 教程详解 #### 一、db4o简介与安装 db4o是一款开源的对象数据库系统,支持Java、.NET 和 Mono等平台。本教程旨在帮助用户快速掌握db4o的基本用法,并提供丰富的资源以支持开发者深入学习。 在开始...
DB4O(Database for Objects)是一款开源的对象数据库管理系统(Object-Relational Mapping,ORM),它允许开发者将Java或.NET对象直接存储到磁盘上,无需转换为传统的表和列的结构。DB4O的设计理念是简化数据存储,...
db4o的.net3.5版本确保了与该框架的兼容性,使开发者能够利用其丰富的特性和库来实现对象持久化。 ### 3. db4o-7.4-net35.msi 这个文件是db4o 7.4版本针对.NET 3.5的安装程序。msi文件是Microsoft Installer格式,...
5. **分布式数据库**:db4o支持多客户端并发访问,可以在分布式环境中运行,实现数据的共享和同步。 6. **动态模式**:db4o允许在运行时动态添加新类和字段,无需预先定义表结构,具有很好的灵活性。 ### 示例程序...
db4o是一个专为Java和.NET开发者设计的开源、轻量级的纯面向对象数据库引擎,提供了一种简单易用的方式来实现对象持久化。这款数据库引擎已被验证具备优秀的性能,根据描述中的基准测试,db4o在与传统持久化方案的...
通过NQ,可以方便地实现对对象属性的匹配,如查询所有年龄大于30的人,只需创建一个年龄为30的对象,然后使用db4o的query()方法进行查找。 **三、SDOA(SODA - Simple Object Database Access)** SDOA是db4o提供的...
《db4o 权威指南》是一本深入探讨db4o这一开源面向对象数据库系统的专业书籍,对于Java开发者来说尤其有价值。db4o是Database for Objects的缩写,它允许开发者以自然、直观的方式存储和检索Java对象,无需编写SQL...
- 打开一个DB4O库:首先,你需要创建一个`Configuration`实例,并使用`Db4o.openServer()`或`Db4o.openClient()`方法来连接或打开数据库。这通常涉及到指定数据库的URL、端口以及配置参数。 - 存储对象:使用`...
5. **分布式能力**:DB4O支持多客户端共享同一数据库,可以实现数据的分布式存储和访问。 6. **内存优化**:DB4O能根据需要动态加载和卸载对象,节省内存资源。 7. **事务支持**:DB4O提供ACID(原子性、一致性、...
Db4o,全称为“Database for Objects”,是一个开源的对象数据库系统,专为.NET和Java平台设计。它允许开发者直接在对象上进行数据操作,而无需传统的ORM(对象关系映射)层,简化了数据存储和检索的过程。这个...
DB4o(Database for Objects)是一款开源的对象数据库系统,它允许开发者直接将对象持久化到数据库中,无需进行额外的映射或者数据访问层(DAL)的开发。这个数据库系统设计的目标是简化对象关系映射(ORM)的过程,...
对于学习和理解对象数据库以及如何在Java应用程序中实现对象持久化的开发者来说,db4o仍然是一个有价值的参考资料。在压缩包中的“db4o”文件可能包含了db4o的库文件、示例代码、文档等资源,可以帮助深入理解和使用...
db4o-8.0-tutorial.pdf 是该版本的官方教程文档,它涵盖了DB4O 8.0的主要特性和使用方法,包括如何配置、连接、查询和管理数据库。通过这份教程,用户可以深入理解DB4O的工作原理,学习如何将对象持久化到数据库中,...
为了使用Db4o,开发者需要将对应的DLL添加到项目引用中,并根据项目需求配置数据库连接和存储参数。 总的来说,Db4o是一个强大的对象数据库解决方案,它简化了.NET开发中的数据管理,使得对象模型和数据库模型保持...
" 这意味着db4o具有轻量级、快速启动和运行的特点,对于那些需要快速实现数据存储功能的项目来说,是一个理想的选择。尤其是在开发桌面应用时,db4o可以极大地简化数据管理,因为它允许直接将对象存储和检索,而无需...