CompletableFuture < Void > handleLifespanExpireEntry ( K key , V value , long lifespan , boolean skipLocking ) { // The most used case will be a miss so no extra read before if ( expiring . putIfAbsent ( key , key ) == null ) { if ( trace ) { log . tracef ( "Submitting expiration removal for key %s which had lifespan of %s" , toStr ( key ) , lifespan ) ; } AdvancedCache < K , V > cacheToUse = skipLocking ? cache . withFlags ( Flag . SKIP_LOCKING ) : cache ; CompletableFuture < Void > future = cacheToUse . removeLifespanExpired ( key , value , lifespan ) ; return future . whenComplete ( ( v , t ) -> expiring . remove ( key , key ) ) ; } return CompletableFutures . completedNull ( ) ; }
holds the lock until this CompletableFuture completes . Without lock skipping this would deadlock .