public T get ( ) { T object ; while ( true ) { // 1. get the next free object int p = m_put . get ( ) ; int g = m_get . get ( ) ; if ( g >= p ) { // get index hits the put index, implying empty pool if ( p >= LIMIT ) { // put pointer wrapped around. rewind both indexes. m_get . set ( 0 ) ; m_put . set ( 0 ) ; } return null ; } // 2. conquer this cell by incrementing the get index if ( ! m_get . compareAndSet ( g , g + 1 ) ) { // some other thread got here first. try again. continue ; } // 3. retrieve the object at the get index int index = g % m_arraySize ; AtomicReference < T > reference = m_array [ index ] ; object = reference . get ( ) ; if ( object == null ) { // getting here is rare. it happens when: // 1. put() is called on an empty pool (p==g) // 2. put() increments the put pointer (p==g+1) // 3. get() is called and finds g < p // 4. get() takes the object at g (which is null) // 5. put() puts the object at g continue ; } // 4. change the reference to null so no other get() takes the // same element, and no other put() replaces it with another. if ( reference . compareAndSet ( object , null ) ) { return object ; } // getting here is rare. the object that was supposedly conquered // locally was either replaced by a different object or replaced // with null, in the same cell. } }
gets an object from the pool