private QNode reclean ( ) { /* * cleanMe is, or at one time was, predecessor of cancelled * node s that was the tail so could not be unspliced. If s * is no longer the tail, try to unsplice if necessary and * make cleanMe slot available. This differs from similar * code in clean() because we must check that pred still * points to a cancelled node that must be unspliced -- if * not, we can (must) clear cleanMe without unsplicing. * This can loop only due to contention on casNext or * clearing cleanMe. */ QNode pred ; while ( ( pred = this . cleanMe . get ( ) ) != null ) { QNode t = getValidatedTail ( ) ; QNode s = pred . next ; if ( s != t ) { QNode sn ; if ( s == null || s == pred || s . get ( ) != s || ( sn = s . next ) == s || pred . casNext ( s , sn ) ) { this . cleanMe . compareAndSet ( pred , null ) ; } } else { break ; } } return pred ; }
Tries to unsplice the cancelled node held in cleanMe that was previously uncleanable because it was at tail .