重新实现的db4o连接池

【虎.无名】看了[url=http://www.blogjava.net/rosen/archive/2006/09/27/72314.html]Roson的db4o连接池实现[/url],似乎存在一些问题:
1,使用sleep或者wait/notify是为了避免循环忙等待,这个非常消耗CPU资源,否则不适合用于生产环境。
2,限制在Jdk1.5以上版本了,并非必要。
3,用户应该可以选择本地模式,还是远程模式;对于后者,需要远程服务器和端口,同时,在代码上,就无需Db4o.openServer了。
于是乎,一时手痒,就重新实现了一个,看看测试效果,虽然达到了互斥,但是db4o内部似乎还存在一些问题。set进去的类,没有成功保存,奇怪中。
[code]/**
* 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 -------");
}
}[/code]需要的辅助类如下,用于配置log4j以及随机等待。
[code]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) {
// 忽略
}
}
}[/code]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值