codefans

导航

<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

统计

常用链接

留言簿(2)

随笔分类

随笔档案

文章分类

文章档案

程序设计链接

搜索

最新评论

阅读排行榜

评论排行榜

从一个ConnectionPool的实现看design pattern的运用 (source code for Java 1.1)

ConnectionPool.java:

public interface ConnectionPool{
    Connection getConnection()
    throws test.res.ResourceNotAvailableException, SQLException;
    Connection getConnection(long timeout)
    throws test.res.ResourceTimeOutException, SQLException;
    void clear();
}

ConnectionHome.java:

public interface ConnectionHome{
 void releaseConnection(Connection conn);
}

ConnectionPooling.java:

public interface ConnectionPooling extends ConnectionHome{
    Connection getConnection()
    throws test.res.ResourceNotAvailableException, SQLException;
   
    Connection getConnection(long timeout)
    throws test.res.ResourceTimeOutException, SQLException;
    void clear();
    void releaseConnection(Connection conn);
}

ConnectionFactory.java:

public interface ConnectionFactory{
 public Connection createConnection()throws SQLException;
}

PooledConnection.java: (for Connection in Java 1.1.8)


public final class PooledConnection implements Connection{
    private interface ConnectionState{
        ConnectionState close();
        boolean isClosed();
        Connection getOpenConnection()
        throws SQLException;
    }
    private static class ClosedConnection implements ConnectionState{
        public final ConnectionState close(){return this;}
        public final Connection getOpenConnection()
        throws SQLException{
            throw new SQLException("Connection closed");
        }
        public final boolean isClosed(){return true;}
        private ClosedConnection(){}
        private static final ConnectionState _instance = new ClosedConnection();
        static ConnectionState instance(Connection conn, ConnectionHome home){return _instance;}
    }
   
    private static class OpenConnection implements ConnectionState{
     private final ConnectionHome home;
        private final Connection conn;
        public final ConnectionState close(){
                home.releaseConnection(conn);
                return ClosedConnection.instance(conn, home);
        }
        public final Connection getOpenConnection()
        {return conn;}
        public final boolean isClosed(){return false;}
        OpenConnection(Connection conn, ConnectionHome home){
         this.conn = conn; this.home = home;
        }
        static ConnectionState instance(Connection conn, ConnectionHome home){
         return new OpenConnection(conn, home);
        }
    }
    private ConnectionState state;
    public static Connection decorate(Connection conn, ConnectionHome home)
    throws SQLException{
     return new PooledConnection(conn, home);
    }
   
    private PooledConnection(Connection conn, ConnectionHome home)
    throws SQLException{
        if(conn.isClosed()){
            state = ClosedConnection.instance(conn, home);
        }
        else{
            state = OpenConnection.instance(conn, home);
        }
    }      
    public final boolean isClosed(){
        return state.isClosed();
    }

    public final void close(){
        state = state.close();
    }
    protected void finalize(){
      close();
    }
    private final Connection getOpenConnection()
    throws SQLException
    {return state.getOpenConnection();}
    /*****then, delegate all the other methods****/
    public final Statement createStatement()
    throws SQLException{
        return getOpenConnection().createStatement();
    }
  
    //....
    public final void clearWarnings()throws SQLException{
        getOpenConnection().clearWarnings();
    }
     
 
    public final void commit()throws SQLException{
        getOpenConnection().commit();
    }

    /*
    public final Statement createStatement(int resultSetType,
        int resultSetConcurrency)
    throws SQLException{
        return getOpenConnection().createStatement(resultSetType, resultSetConcurrency);
    }*/
   
    /*
    public final Statement createStatement(int resultSetType,
        int resultSetConcurrency, int resultSetHoldability)
    throws SQLException{
        return getOpenConnection().createStatement(resultSetType,
            resultSetConcurrency, resultSetHoldability);
    }*/
   
   
    public final boolean getAutoCommit()throws SQLException{
        return getOpenConnection().getAutoCommit();
    }
    public final String getCatalog()throws SQLException{
        return getOpenConnection().getCatalog();
    }
    /*
    public final int getHoldability()throws SQLException{
        return getOpenConnection().getHoldability();
    }*/
     
    public final DatabaseMetaData getMetaData()throws SQLException{
        return getOpenConnection().getMetaData();
    }
    public final int getTransactionIsolation()throws SQLException{
        return getOpenConnection().getTransactionIsolation();
    }
    /*
    public final Map getTypeMap()throws SQLException{
        return getOpenConnection().getTypeMap();
    }*/
    public final SQLWarning getWarnings()throws SQLException{
        return getOpenConnection().getWarnings();
    }

    public final boolean isReadOnly()throws SQLException{
        return getOpenConnection().isReadOnly();
    }
    public final String nativeSQL(String sql)throws SQLException{
        return getOpenConnection().nativeSQL(sql);
    }
    public final CallableStatement prepareCall(String sql)throws SQLException{
        return getOpenConnection().prepareCall(sql);
    }
    /*
    public final CallableStatement prepareCall(String sql,
        int resultSetType, int resultSetConcurrency)
    throws SQLException{
        return getOpenConnection().prepareCall(sql, resultSetType, resultSetConcurrency);
    }
     
    public final CallableStatement prepareCall(String sql,
        int resultSetType, int resultSetConcurrency, int resultSetHoldability)
    throws SQLException{
        return getOpenConnection().prepareCall(sql, resultSetType,
            resultSetConcurrency, resultSetHoldability);
    }*/
     
    public final PreparedStatement prepareStatement(String sql)
    throws SQLException{
        return getOpenConnection().prepareStatement(sql);
    }
    /*
    public final PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
    throws SQLException{
        return getOpenConnection().prepareStatement(sql, autoGeneratedKeys);
    }

    public final PreparedStatement prepareStatement(String sql, int[] columnIndexes)
    throws SQLException{
        return getOpenConnection().prepareStatement(sql, columnIndexes);
    }
   
    public final PreparedStatement prepareStatement(String sql,
        int resultSetType, int resultSetConcurrency)
    throws SQLException{
        return getOpenConnection().prepareStatement(sql,
            resultSetType, resultSetConcurrency);
    }
     
    public final PreparedStatement prepareStatement(String sql,
        int resultSetType, int resultSetConcurrency, int resultSetHoldability)
    throws SQLException{
        return getOpenConnection().prepareStatement(sql,
            resultSetType, resultSetConcurrency, resultSetHoldability);
    }
     
    public final PreparedStatement prepareStatement(String sql,
        String[] columnNames)
    throws SQLException{
        return getOpenConnection().prepareStatement(sql, columnNames);
    }
     
    public final void releaseSavepoint(Savepoint savepoint)throws SQLException{
        getOpenConnection().releaseSavepoint(savepoint);
    }*/
    public final void rollback()throws SQLException{
        getOpenConnection().rollback();
    }
    /*
    public final void rollback(Savepoint savepoint)
    throws SQLException{
        getOpenConnection().rollback(savepoint);
    }*/
     
    public final void setAutoCommit(boolean autoCommit)
    throws SQLException{
        getOpenConnection().setAutoCommit(autoCommit);
    }
     
    public final void setCatalog(String catalog)
    throws SQLException{
        getOpenConnection().setCatalog(catalog);
    }
    /*
    public final void setHoldability(int holdability)
    throws SQLException{
        getOpenConnection().setHoldability(holdability);
    }*/        
    public final void setReadOnly(boolean readOnly)
    throws SQLException{
        getOpenConnection().setReadOnly(readOnly);
    }
    /*
    public final Savepoint setSavepoint()throws SQLException{
        return getOpenConnection().setSavepoint();
    }
     
    public final Savepoint setSavepoint(String name)
    throws SQLException{
        return getOpenConnection().setSavepoint(name);
    }*/
     
    public final void setTransactionIsolation(int level)
    throws SQLException{
        getOpenConnection().setTransactionIsolation(level);
    }
    /*public final void setTypeMap(Map map)throws SQLException{
        getOpenConnection().setTypeMap(map);
    }*/

    /*************************************************************************************************/
   

}

ConnectionPooling2Pool.java:

public class ConnectionPooling2Pool implements ConnectionPool{
    public final Connection getConnection()
    throws test.res.ResourceNotAvailableException, SQLException{
     return PooledConnection.decorate(pooling.getConnection(), pooling);
    }
    public final Connection getConnection(long timeout)
    throws test.res.ResourceTimeOutException, SQLException{
     return PooledConnection.decorate(pooling.getConnection(timeout), pooling);
    }
    public final void clear(){
     pooling.clear();
    }
    private final ConnectionPooling pooling;
    private ConnectionPooling2Pool(ConnectionPooling pooling){
     this.pooling = pooling;
    }
    public static ConnectionPool decorate(ConnectionPooling pooling){
     return new ConnectionPooling2Pool(pooling);
    }
}

ConnectionPoolingImpl.java: (a simple implementation of ConnectionMan)

public class ConnectionPoolingImpl implements ConnectionPooling
{
    private int client=0;
    private final Vector freeConn = new Vector();
    private final int maxConn;
    private final ConnectionFactory factory;

    static public ConnectionPooling instance(ConnectionFactory factory, int max){
     return new ConnectionPoolingImpl(factory, max);
    }
   
    private ConnectionPoolingImpl(ConnectionFactory factory, int max){
     this.factory = factory;
     this.maxConn = max;
    }

    public final synchronized void releaseConnection(Connection conn)
    {
        freeConn.addElement(conn);
        client--;
        notify();
    }

    public final synchronized Connection getConnection()
    throws ResourceNotAvailableException, SQLException
    {
        Connection conn = null;
        if(freeConn.size() > 0)
        {
            conn = (Connection)freeConn.lastElement();
            freeConn.removeElementAt(freeConn.size()-1);
        }
        else if(client < maxConn)
        {
            conn = factory.createConnection();
        }
        if(conn != null)
        {
            client++;
            return conn;
        }
        else
        {
            throw new ResourceNotAvailableException();
        }
    }

    public final synchronized Connection getConnection(long timeout)
    throws ResourceTimeOutException, SQLException
    {
        for(long startTime = new java.util.Date().getTime();;)
        {
            try
            {
                return getConnection();
            }
            catch(ResourceNotAvailableException e1)
            {
                try
                {
                    wait(timeout);
                }
                catch(InterruptedException e2)
                {}
                if((new java.util.Date().getTime() - startTime) >= timeout)
                {
                    throw new ResourceTimeOutException();
                }
            }
        }
    }


    public final synchronized int getfreeconn(){
        return freeConn.size();
    }
    public final int getmaxConn(){
        return maxConn;
    }
    public final synchronized int getclient(){
        return client;
    }
    public final synchronized void setclient(){
        client=0;
    }

    public final synchronized void clear(){
  closeAll();
        freeConn.removeAllElements();
    }
    private final void closeAll(){
        for(int i=0; i<freeConn.size();i++)
        {
            final Connection conn = (Connection)freeConn.elementAt(i);
            try{
                conn.close();
            }
            catch(SQLException sqlException){}
        }
    }
    protected void finalize(){
     closeAll();
    }   
}

 

ConnectionFactoryImpl.java:

public class ConnectionFactoryImpl
{
    private ConnectionFactoryImpl(){}
    static public ConnectionFactory instance(final String driver, final String url,
     final String user, final String pwd)
    throws SQLException, ClassNotFoundException{
  final Class driverClass = Class.forName(driver);
  return new ConnectionFactory(){
   private final Class keeper = driverClass;
   public final Connection createConnection()
   throws SQLException{
    return DriverManager.getConnection(url,user,pwd);
   }
  };
    }
    static public ConnectionFactory instance(final String driver, final String url)
    throws SQLException, ClassNotFoundException{
  final Class driverClass = Class.forName(driver);
  return new ConnectionFactory(){
   private final Class keeper = driverClass;
   public final Connection createConnection()
   throws SQLException{
    return DriverManager.getConnection(url);
   }
  };
 } 
}

TestConnectionPool.java:

public class TestConnectionPool{
 public static void test(String driver, String url, String user, String pwd)
 throws java.sql.SQLException, test.res.ResourceNotAvailableException, test.res.ResourceTimeOutException, ClassNotFoundException{
  final ConnectionPool pool = ConnectionPooling2Pool.decorate(
   ConnectionPoolingImpl.instance(
    ConnectionFactoryImpl.instance(driver, url, user, pwd),
    1000)
   );
 }
}

ResourceNotAvailableException.java:

public class ResourceNotAvailableException extends RuntimeException{
 public ResourceNotAvailableException(String msg){super(msg);}
 public ResourceNotAvailableException(){}
}

ResourceTimeOutException.java:

public class ResourceTimeOutException extends Exception{
 public ResourceTimeOutException(String msg){super(msg);}
 public ResourceTimeOutException(){}
}


相关文章
对该文的评论
CrazyJavar ( 2002-08-29)
public final synchronized Connection getConnection(long timeout)
    throws ResourceTimeOutException, SQLException
    {
        for(long startTime = new java.util.Date().getTime();;)
        {
            try
            {
                return getConnection();
            }
            catch(ResourceNotAvailableException e1)
            {
                try
                {
                    wait(timeout);
                }
                catch(InterruptedException e2)
                {}
                if((new java.util.Date().getTime() - startTime) >= timeout)
                {
                    throw new ResourceTimeOutException();
                }
            }
        }
    }

众所周知,wait(timeout);,当线程醒来后,所花费的时间一定大于等于timeout,所以,照你这么写,只要线程wait()了,那么就一定会抛出资源无效的异常。那么wait还有什么作用呢?

posted on 2005-11-22 11:51 春雷的博客 阅读(130) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: