【虎.无名】看了
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) {
// 忽略
}
}
}
分享到:
相关推荐
http://www.db4o.com db4o的官网,可下载最新版本,jar包在项目的database目录下,若构建路径报错请重新添加
对象数据库db4o的示例程序,对象数据库db4o, 对象数据库db4o
描述了db4o的信息要点和使用指南,讲述了一些特殊类,及其基本的使用
db4o8.0以及db4o中文操作指南
db4o 是一个开源的纯面向对象数据库引擎,对于 Java 与 .NET 开发者来说都是一个简单易用的对象持久化工具,使用简单。同时,db4o 已经被第三方验证为具有优秀性能的面向对象数据库, 下面的基准测试图对 db4o 和...
db4o ,net db4o ,net db4o ,net db4o ,net
For the fastest start with db4o please work through the tutorial, available in different formats in the following folder: ./doc/tutorial/ If you are working with db4o for Java, it is recommended...
db4o .net2.0 db4o .net2.0db4o .net2.0 db4o .net2.0db4o .net2.0
可以查看、删除DB4O数据库中的数据,支持*.yap、*.db、*.data等DB4O数据库
DB4O 笔记+常用 JAR包 DB4O 笔记+常用 JAR包 DB4O 笔记+常用 JAR包 DB4O 笔记+常用 JAR包 DB4O 笔记+常用 JAR包
db4o最后发布的版本,包含全部源码、jar包,eclipse下的对象查看插件、全部说明文档等。
该资源为 db4o 之旅 系列文章: 1.介绍了面向对象数据库 db4o 的基本特性,并且与传统关系型数据库以及 OR 映射技术做了比较分析,读者可以体验到 db4o 的全新的面向对象存储的理念,并且给出了性能测试数据。 2....
DB4O 介绍信息.有兴趣的可以看看,了解一下.
非常好的Db4o资料,包括Db4o的七章内容详细介绍及相关的论文。
《DB4O系统应用之起步篇》.《DB4O系统应用之起步篇》.《DB4O系统应用之起步篇》.
DB4O 8.0 Object Manager Enterprise 对象浏览器,db4o-8.0-tutorial.pdf
db4o 权威指南 pdf 非常好
本资料转自网上,仅供学习DB4O开发教程使用
db4o 是一款开放源码对象导向数据库,能使 Java 和 .NET 开发人员不但大幅减低开发时间和成本, 同时能带来前所未有的效能. 另外, db4o 独有的对象导向数据库引擎能应用于免数据库管理人的流动装置或桌面平台, 套装...
描述了DB4O的基础知识,同时其中还包含有更多的DB4O复制系统信息的链接地址.