code: public void clearExpired()
      {
          synchronized (CLEAR_LOCK)
          {
              if (LOCK_STATE.equals(LOCK_STATE_LOCKED))
              {
                  return;
              }
              LOCK_STATE = LOCK_STATE_LOCKED;
          }
          long expireRunStamp = System.currentTimeMillis();
          if (nextTimeSomeExpired != NO_OBJECTS && expireRunStamp >= nextTimeSomeExpired)
          {
              synchronized (objects)
              {
                  try
                  {
                      //remove obj
                      ArrayList set = new ArrayList(objects.keySet());
                      for (Iterator iterator = set.iterator(); iterator.hasNext(); )
                      {
                          Object key = iterator.next();
                          Long timeToExpire = objectTimeStamps.get(key) + timeToLive;
                          if (timeToExpire < expireRunStamp)
                          {
                              objects.remove(key);
                              objectTimeStamps.remove(key);
                          }
                      }
                      findNextExpireTime();
                  }
                  catch (Exception e)
                  {
                      e.printStackTrace();
                  }
              }
          }
          LOCK_STATE = LOCK_STATE_UNLOCKED;
      }
docs: Clear all expired values, only if needed (this provided by storing time of nearest object expiration)
  After removal objects calls findNextExpireTime(), to set next time to clearExpired.
  <p>
  This method called in almost all methods (containsKey, containsValue, get, isEmpty)