大家看我這段程式碼有什麼問題麼?

escape發表於2005-10-24
package org.jelly.pool.impl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.jelly.pool.AbstractConnectionPool;
import org.jelly.pool.exceptions.ServerShutDownException;

public class ConnectionPoolImpl extends AbstractConnectionPool {

private static Log logger = LogFactory.getLog(ConnectionPoolImpl.class);

// jdbc相當的引數宣告
private String jdbcUserName;
private String jdbcPassword;
private String jdbcUrl;
private String jdbcDriverClass;

// 連線池大小的控制變數宣告
private int minimum;
private int maximum;
private static final int DEFAULT_SIZE = 100;
private static final int DEFAULT_MIN_SIZE = 100;
private static final int DEFAULT_MAX_SIZE = 300;
private static final int DEFAULT_WAIT_TIMEOUT = 1000;
private static final String DEFAULT_METHOD_CLOSE = "close";

// 存放資料庫連線的集合
private List usedConnection;
private List availableConnection;

// 連線池的標誌位
private boolean isShutDown = false;

// 執行緒對像
private Thread woker = null;

// lock object
Object lock = new Object();

public ConnectionPoolImpl(String jdbcUserName, String jdbcPassword, String jdbcUrl, String jdbcDriverClass, int minimum, int maximum) {
this.jdbcUserName = jdbcUserName;
this.jdbcPassword = jdbcPassword;
this.jdbcUrl = jdbcUrl;
this.jdbcDriverClass = jdbcDriverClass;
this.minimum = minimum;
this.maximum = maximum;
usedConnection = new LinkedList();
availableConnection = new LinkedList();
System.out.println("connection pool is started...");
System.out.println("jdbcUserName: " + jdbcUserName);
System.out.println("jdbcPassword: " + jdbcPassword);
System.out.println("jdbcUrl: " + jdbcUrl);
System.out.println("jdbcDriverClass: " + jdbcDriverClass);
try {
Driver driver = (Driver)Class.forName(jdbcDriverClass).newInstance();
DriverManager.registerDriver(driver);
makeMinimumConnection(minimum);
} catch (SQLException ex) {
throw new RuntimeException("cannot register jdbc driver or cannot get conection.");
} catch (ClassNotFoundException cnfe) {
throw new RuntimeException("cannot found driver class: ['" + jdbcDriverClass + "'].");
} catch(InstantiationException ie) {
throw new RuntimeException("canoot instance object");
} catch(IllegalAccessException lae) {
throw new RuntimeException("access dined");
}

startThread();
}

// public ConnectionPoolImpl(String jdbcUserName, String jdbcPassword, String jdbcUrl, String jdbcDriverClass, int minimum) {
// this(jdbcUserName, jdbcPassword, jdbcUrl, jdbcDriverClass, minimum, DEFAULT_MAX_SIZE);
// }
//
// public ConnectionPoolImpl(String jdbcUserName, String jdbcPassword, String jdbcUrl, String jdbcDriverClass, int maximum) {
// this(jdbcUserName, jdbcPassword, jdbcUrl, jdbcDriverClass, minimum, DEFAULT_MIN_SIZE);
// }

public ConnectionPoolImpl(String jdbcUserName, String jdbcPassword, String jdbcUrl, String jdbcDriverClass) {
this(jdbcUserName, jdbcPassword, jdbcUrl, jdbcDriverClass, DEFAULT_MIN_SIZE, DEFAULT_MAX_SIZE);
}

// 啟動連線池執行緒,子類必須H這個方法.
protected void startThread() {
woker = new Thread(this);
System.out.println("start thread...");
woker.start();
}

// 建立最小連線的數.
protected int makeMinimumConnection(int minimum) throws SQLException {
for (int i = 0; i < minimum; i++) {
System.out.println("iterator i: " + i);
availableConnection.add(makeConnection());
}
return 0;
}

protected void loop() {
System.out.println("loop");
while (!isShutDown) {
if (minimum < getAvailableSize()) {
for (int i = 0; i < getAvailableSize(); i++) {
Connection conn = (Connection)availableConnection.remove(0);
try {
conn.close();
} catch (SQLException ex) {
throw new RuntimeException("cannot close connection");
}
}
} else {
for (int i = getAvailableSize(); i < minimum; i++) {
try {
availableConnection.add(makeConnection());
} catch (SQLException ex) {
throw new RuntimeException("cannot create connection for pool");
}
}
}
try {
lock.wait(DEFAULT_WAIT_TIMEOUT);
} catch (InterruptedException ie) {
throw new RuntimeException("error");
}
System.out.println("available connection total is: " + getAvailableSize());
}
}

protected void shutDown() {

}

private Connection makeConnection() throws SQLException {
//_Connection conn = null;
if (jdbcUserName.length() > 0) {
System.out.println("create connection proxy for pool");
return new _Connection(DriverManager.getConnection( jdbcUrl, jdbcUserName, jdbcPassword)).getConnection();
} else {
return new _Connection(DriverManager.getConnection(jdbcUrl)).getConnection();
}
}

private Connection getInternalConnection() {
Connection result = null;
if (!availableConnection.isEmpty()) {
result = (Connection)availableConnection.remove(0);
} else if (usedConnection.size() < maximum) {
try {
result = makeConnection();
} catch (SQLException ex) {
throw new RuntimeException("cannot create connection for pool");
}
}
if (null != result) {
usedConnection.add(result);
}

return result;
}

private int getAvailableSize() {
return availableConnection.size();
}

private int getTotal() {
return (availableConnection.size() + usedConnection.size());
}

public synchronized Connection getConnection() {
if (isShutDown) {
throw new ServerShutDownException("the connection pool was shut down...");
}
Connection result = getInternalConnection();
return result;
}

public void exit() {
isShutDown = true;
}

public int getMinimum() {
return this.minimum;
}

public int getMaximum() {
return this.maximum;
}

/* (non-Javadoc)
* @see org.jelly.pool.ConnectionPool#getConnectionWaitTime(int)
*/
public Connection getConnectionWaitTime(int time) {
// TODO Auto-generated method stub
return null;
}
private class _Connection implements InvocationHandler {

private Connection conn;

public _Connection(Connection conn) {
this.conn = conn;
}

public Connection getConnection() {
//this.conn = conn;
return (Connection)Proxy.newProxyInstance( conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), this);
}

public Object invoke(Object proxy, Method m, Object[] args) {
System.out.println(m.getName());
Object obj = null;
if (DEFAULT_METHOD_CLOSE.equals(m.getName()) && minimum > getAvailableSize()) {
availableConnection.add(conn);
lock.notify();
} else {
try {
obj = m.invoke(conn, args);
}catch(IllegalAccessException el) {

}catch(IllegalArgumentException ia) {

}catch(InvocationTargetException ite) {

}
}

return obj;
}
}
}

lock.wait();這一句說
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException: current thread not owner
是什麼意思呢?

相關文章