import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReferenceArray;

/**
 * A lock-free object pool.
 */
public class ObjectPool<E> implements IObjectFactory<E> {
	/**
	 * The underneath object factory.
	 */
    private final IObjectFactory<E> factory;
    /**
     * The cached object stack.
     */
    private final AtomicReferenceArray<E> objects;
    /**
     * The index in {@link #objects} of the first empty element.
     */
    private final AtomicInteger top = new AtomicInteger(0);


    /**
     * Constructor.
     * @param factory the IObjectFactory creating and freeing objects.
     * @param cap the maximum number of objects cached.
     */
    public ObjectPool(IObjectFactory<E> factory, int cap) {
        this.factory = factory;
        this.objects = new AtomicReferenceArray<>(cap);
    }
    
    @Override
    public E alloc() {
        while (true) {
            // Try reserve a cached object in objects
            int n;
            do {
                n = top.get();
                if (n == 0) {
                    // No cached oobjects, allocate a new one
                    return factory.alloc();
                }
            } while (!top.compareAndSet(n, n - 1));
            // Try fetch the cached object
            E e = objects.getAndSet(n, null);
            if (e != null) {
                return e;
            }
            // It is possible that the reserved object was extracted before
            // the current thread tried to get it. Let's start over again.
        }
    }
    
    @Override
    public void free(E e) {
        while (true) {
            // Try reserve a place in this.objects for e.
            int n;
            do {
                n = top.get();
                if (n == objects.length()) {
                    // the pool is full, e is not cached.
                    factory.free(e);
                }
            } while (!top.compareAndSet(n, n + 1));
            // Try put e at the reserved place.
            if (objects.compareAndSet(n + 1, null, e)) {
                return;
            }
            // It is possible that the reserved place was occupied before
            // the current thread tried to put e in it. Let's start over again.
        }
    }
}

@@ -133,16 +133,327 @@
 t pool.%0A
+ * This object pool uses AtomicReferenceArray and AtomicInteger but%0A * no blocking locks.%0A *%0A * NOTE The user should not depend on the assumption ObjectPool will%0A * cache all the objects even if the capacity is big enough.%0A * But the situation of objects not cached (with enough capacity)%0A * happens very rare.%0A
  */%0Apubl
@@ -510,14 +510,20 @@
 %3E %7B%0A
-%09/**%0A%09
+    /**%0A    
  * T
@@ -556,9 +556,12 @@
 ry.%0A
-%09
+    
  */%0A
@@ -1240,32 +1240,35 @@
          // Try 
+to 
 reserve a cached
@@ -1416,17 +1416,16 @@
  cached 
-o
 objects,
@@ -1577,16 +1577,19 @@
  // Try 
+to 
 fetch th
@@ -1761,103 +1761,147 @@
  the
- 
 re
-served object was extracted before%0A            // the current thread tried to get it.
+ is no cached object in the reserved%0A            // place. E.g. the place was just reserved and not set yet.%0A            //
  Let's 
+simply 
 star
@@ -1898,38 +1898,32 @@
 imply start over
- again
 .%0A        %7D%0A    
@@ -2013,16 +2013,19 @@
  // Try 
+to 
 reserve 
@@ -2190,17 +2190,17 @@
      // 
-t
+T
 he pool 
@@ -2351,16 +2351,19 @@
  // Try 
+to 
 put e at
@@ -2422,20 +2422,16 @@
 AndSet(n
- + 1
 , null, 
@@ -2540,16 +2540,17 @@
 occupied
+.
  before%0A
@@ -2605,21 +2605,124 @@
  in it. 
-Let's
+E.g. the place was%0A            // just reserved in alloc() but not moved out yet%0A            // Let's simply
  start o
@@ -2728,14 +2728,8 @@
 over
- again
 .%0A  

Update ObjectPool.java