Resource Pooling In Java Produce a resource pool for heavy lifting
JDJ Issue 05-11; p.26

Listing 1
import java.util.Stack;

public class Pool
{
  // This is a storage
  private Stack stack = new Stack();

  public Object pop(long time)
  {
    long timeLimit =
      System.currentTimeMillis()+time*1000;

    while(System.currentTimeMillis()
      < timeLimit)
    {
      Object anObject = tryPop();
      if( null != anObject )
        return anObject;

      // Sleep for time*1000/10, i.e. 1/10
      // of time allowed.
      Thread.sleep(time*100);
    }

    return null;
  }

  public synchronized Object tryPop()
  {
    if(stack.empty())
      return null;

    return stack.pop();
  }

  public void push(Object obj)
  {
    stack.push(obj);
  }

  public int size()
  {
    return stack.size();
  }
}
Listing 2
public void usageExample() throws Exception
{
  Resource res = null;
  try
  {
    res = (Resource) staticPool.pop(10);

    if( null == res )
      throw new Exception("Resource is
      unavailable.");

    // Do something with the resource
  }
  finally
  {
    if( null != res )
      staticPool.push(res);
  }
}
Listing 3
import java.sql.*;

public class DbConnectionsPool
  extends Pool implements Runnable
{
  // Connections counting
  private int maxConnections;
  private int currentConnections = 0;

  // Thread that does connection checking
  private Thread checking = null;
 
  // Time interval (in seconds) between
  // connection checking attempts.
  private static final int
               CHECKING_INTERVAL=60;

  // JDBC-specific variables go here
  ....

  public DbConnectionsPool(
    int maxConnections, String dbDriver,
    String dbUrl, String dbUser,
    String dbPassword)
  {
    // Initialization of internal
    // variables goes here
    ....

    // Create a checking thread
    checking = new Thread(this);
    checking.setDaemon(true);
    checking.start();
  }

  public Object pop(long timeOut)
  {
    Connection conn = null;

    // Try to get it from the internal stack.
    conn = (Connection) tryPop();
    if( null != conn )
      return conn;

    // Try to create another connection
    // if possible.
    if( currentConnections < maxConnections )
    {
      conn = createConnection();
      if( null != conn )
      {
        currentConnections++;
        return conn;
      }
    }

    // Wait if cannot do any better
    return super.pop(timeOut);
  }

  private Connection createConnection()
  {
    // Code to create a JDBC connection
    // goes here
    ....
  }

  private boolean isGood(Connection conn)
  {
    boolean result = true;
    Statement stmt = null;
    try
    {
      stmt = conn.createStatement();
      if( null != stmt )
        stmt.execute("rollback work");
    }
    catch(SQLException e)
    {
      result = false;
    }
    finally
    {
      if( null != stmt )
      stmt.close();
    }

    return result;
  }

  public void run()
  {
    Stack holding = new Stack();

    while( true )
    {
      // Wait CHECKING_INTERVAL seconds
      Thread.sleep(
        CHECKING_INTERVAL*1000);

      // Get all available connections
      // into a temporary stack
      while( true )
      {
         Connection conn = (Connection) tryPop();
         if( null == conn )
           break;

         holding.push(conn);
      }

      // Go over the stack and check connections
      while( !holding.empty() )
      {
        Connection conn = (Connection) holding.pop();
        if( isGood(conn) )
        {
          // Put it back if it's good
          push(conn);
        }
        else
        {
          // Drop it if it's bad
          conn.close();
          currentConnections--;
        }
      }
    }
  }
}

Listing 4
import org.omg.CORBA.*;

public class CORBAConnectionsPool
{
  private Hashtable
    connectionPools = new Hashtable();
  private ORB orb = ORB.init();
  private final int maxConnections = 10;

  public org.omg.CORBA.Object pop(String id,
    String serviceName, long timeOut)
  {
    // Try can get a connection pool from
    // the hashtable.
    Pool pool =
      (Pool)connectionPools.get(
         serviceName);
    if( pool == null )
    {
      // Initialize ConnectionPool
      pool = new Pool();

      connectionPools.put(serviceName,
        pool);
    }

    // Try can get a connection from the pool
    org.omg.CORBA.Object corbaObj =
    (org.omg.CORBA.Object) pool.tryPop();
    if( corbaObj == null )
    {
      // Try to create another connection
      if( pool.size() < maxConnections )
      {
        // WARNING: this is VisiBroker-
        // specific call
        corbaObj =
          ((com.visigenic.vbroker.orb.ORB)orb).
            bind(id, serviceName, null, null);

        if( corbaObj != null )
          return corbaObj;
      }
    }

    if( corbaObj == null )
      corbaObj =
       (org.omg.CORBA.Object)pool.pop(timeOut);

    return corbaObj;
  }

  public org.omg.CORBA.Object pop(
    String serviceName, long timeOut)
  {
    String id = GenericObjectHelper.id();
    return pop(id, serviceName, timeOut);
  }

  public void push(String serviceName,
    org.omg.CORBA.Object corbaObject)
  {
    ((Pool)connectionPools.get(serviceName)).
     push(corbaObject);
  }
}

Listing 5
void ambiguousExample()
 {
  CORBAConnectionsPool connPool =
   new CORBAConnectionsPool();

  org.omg.CORBA.Object corbaObject =
   connPool.getConnection(
     DeviceHelper.id(), "Printer", 10);

  // WRONG!!! It could refer to Bubble
  // interface.
  Laser interface =
    LaserHelper.narrow(corbaObject);
}