import java.util.ArrayList; class PoolItem { boolean inUse = false; Object item; PoolItem(Object item) { this.item = item; } } class ReleasableReference { // Used to build the proxy private PoolItem reference; private boolean released = false; public ReleasableReference(PoolItem reference) { this.reference = reference; } public Object getReference() { if (released) throw new RuntimeException("Tried to use reference after it was released"); return reference.item; } public void release() { released = true; reference.inUse = false; } } class PoolManager { private ArrayList<PoolItem> items = new ArrayList<PoolItem>(); public void add(Object item) { items.add(new PoolItem(item)); } public static class EmptyPoolItem { } public ReleasableReference get() { for (int i = 0; i < items.size(); i++) { PoolItem pitem = (PoolItem) items.get(i); if (pitem.inUse == false) { pitem.inUse = true; return new ReleasableReference(pitem); } } return null; } } interface Connection { Object get(); void set(Object x); void release(); } class ConnectionImplementation implements Connection { public Object get() { return null; } public void set(Object s) { } public void release() { } } class ConnectionPool { // A singleton private static PoolManager pool = new PoolManager(); private ConnectionPool() { } public static void addConnections(int number) { for (int i = 0; i < number; i++) pool.add(new ConnectionImplementation()); } public static Connection getConnection() { ReleasableReference rr = (ReleasableReference) pool.get(); if (rr == null) return null; return new ConnectionProxy(rr); } } class ConnectionProxy implements Connection { private ReleasableReference implementation; public ConnectionProxy(ReleasableReference rr) { implementation = rr; } public Object get() { return ((Connection) implementation.getReference()).get(); } public void set(Object x) { ((Connection) implementation.getReference()).set(x); } public void release() { implementation.release(); } } public class ConnectionPoolProxyDemo { public static void main(String args[]) { try { ConnectionPool.addConnections(5); Connection c = ConnectionPool.getConnection(); c.set(new Object()); c.get(); c.release(); c = ConnectionPool.getConnection(); c.set(new Object()); c.get(); c.release(); c.get(); } catch (Exception e) { System.out.println(e.getMessage()); } } }