When disposing a basic parallel search, each of the searches that have been added to the parallel
algorithm are disposed and the thread pool used for concurrent search execution is released.
349789
@Override
    protected void searchDisposed() {
        // release thread pool
        pool.shutdown();        
        // dispose contained searches
        searches.forEach(s -> s.dispose());
        // dispose super
        super.searchDisposed();
    }
1065513
static void detach() {
        map.get().kill();
        try {
          map.get().join();
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
        }
        map.remove();
    }
1278981
private void pruneIfNeeded(int neededSpace) {
        if ((mTotalSize + neededSpace) < mMaxCacheSizeInBytes) {
            return;
        }
//        if (JusLog.DEBUG) {
//            JusLog.v("Pruning old cache entries.");
//        }
        //todo add queue markers

        long before = mTotalSize;
        int prunedFiles = 0;
        long startTime = System.nanoTime();

        Iterator<Map.Entry<String, CacheHeader>> iterator = mEntries.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, CacheHeader> entry = iterator.next();
            CacheHeader e = entry.getValue();
            boolean deleted = getFileForKey(e.key).delete();
            if (deleted) {
                mTotalSize -= e.size;
            } else {
                //todo add queue markers
//               JusLog.d("Could not delete cache entry for key=%s, filename=%s",
//                       e.key, getFilenameForKey(e.key));
            }
            iterator.remove();
            prunedFiles++;

            if ((mTotalSize + neededSpace) < mMaxCacheSizeInBytes * HYSTERESIS_FACTOR) {
                break;
            }
        }
//todo add queue markers
//        if (JusLog.DEBUG) {
//            JusLog.v("pruned %d files, %d bytes, %d ms",
//                    prunedFiles, (mTotalSize - before), System.nanoTime() - startTime);
//        }
    }
894257
public static void close() {
    synchronized (poolMap) {
      for (Pool pool : poolMap.values()) {
        try {
          pool.close();
        } catch (InterruptedException exception) {
          //eat
        }
      }
      shutdownExecutor();
      poolMap.clear();
    }
  }
789399
private synchronized void expungeStaleEntries()
    {
        if (size == 0) return;
        Object r;
        while ((r = queue.poll()) != null)
        {
            Entry e = (Entry) r;
            unlink(e);
            int h = e.hash;
            int i = indexFor(h, table.length);

            Entry prev = table[i];
            Entry p = prev;
            while (p != null)
            {
                Entry next = p.next;
                if (p == e)
                {
                    if (prev == e)
                        table[i] = next;
                    else
                        prev.next = next;
                    e.next = null;  // Help GC
                    size--;
                    break;
                }
                prev = p;
                p = next;
            }
        }
    }
772332
public void purgeCache() {
        synchronized (users) {
            users.values().stream()
                    .map(Reference::get)
                    .filter(Objects::nonNull)
                    .map(Cleanupable.class::cast)
                    .forEach(Cleanupable::cleanup);
            users.clear();
        }
        userIdByRef.clear();
        servers.values().stream()
                .map(Cleanupable.class::cast)
                .forEach(Cleanupable::cleanup);
        servers.clear();
        channels.values().stream()
                .filter(Cleanupable.class::isInstance)
                .map(Cleanupable.class::cast)
                .forEach(Cleanupable::cleanup);
        channels.clear();
        unavailableServers.clear();
        customEmojis.clear();
        messages.clear();
        messageIdByRef.clear();
        timeOffset = null;
    }
876482
private void closeAndForgetOldResults() {
        Iterator<FieldSearchResultSQLImpl> iter =
                m_currentResults.values().iterator();
        while (iter.hasNext()) {
            FieldSearchResultSQLImpl r = iter.next();
            if (r.isExpired()) {
                logger.debug("listSession " + r.getToken()
                        + " expired; will forget it.");
                iter.remove();
            }
        }
    }
916730
function (threadId) {
        Multiplexer.connections[threadId] && Multiplexer.connections[threadId].release();
        delete Multiplexer.connections[threadId];
    }
1187329
public void remove() {
        Thread thread = Thread.currentThread();
        if (thread instanceof ThreadPool.Worker) {
            Object[] wsLocals = getThreadLocals((ThreadPool.Worker) thread);
            wsLocals[index] = null;
        } else {
            super.remove();
        }
    }
205300
private void cleanup() {
    if (operation instanceof Command && log.isOpen()) {
      try {
        log.release(index);
      } catch (IllegalStateException e) {
      }
    }

    session.release();

    index = 0;
    session = null;
    instant = null;
    operation = null;

    pool.release(this);
  }
741219
void cleanUp() {
    if (threadStarted) {
      return;
    }

    Reference<?> reference;
    while ((reference = queue.poll()) != null) {
      /*
       * This is for the benefit of phantom references. Weak and soft
       * references will have already been cleared by this point.
       */
      reference.clear();
      try {
        ((FinalizableReference) reference).finalizeReferent();
      } catch (Throwable t) {
        logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
      }
    }
  }
638209
public void cleanup() {
		long currentTime = System.currentTimeMillis();

		// remove entries which have exceeded their time to live
		cachedExecutionGraphs.values().removeIf(
			(ExecutionGraphEntry entry) -> currentTime >= entry.getTTL());
	}
779233
public void forceClose() {
        // Move all elements from usedInstances to unusedInstances in a threadsafe way
        for (final T usedInstance : new ArrayList<>(usedInstances)) {
            if (usedInstances.remove(usedInstance)) {
                unusedInstances.add(usedInstance);
            }
        }
        close();
    }
347704
public void purgePoolContents() throws ResourceException {
        if (tc.isEntryEnabled()) {
            Tr.entry(this, tc, "purgePoolContents", gConfigProps.cfName);
        }
        ArrayList<MCWrapper> destroyMCWrappeList = new ArrayList<MCWrapper>();
        synchronized (destroyMCWrapperListLock) {
            for (int j = 0; j < gConfigProps.getMaxFreePoolHashSize(); ++j) {
                synchronized (freePool[j].freeConnectionLockObject) {
                    /*
                     * If a connection gets away, by setting fatalErrorNotificationTime will
                     * guaranty when the connection is returned to the free pool, it will be
                     */
                    freePool[j].incrementFatalErrorValue(j);
                    /*
                     * Move as many connections as we can in the free pool to the destroy list
                     */
                    if (freePool[j].mcWrapperList.size() > 0) {
                        //freePool[j][i].removeCleanupAndDestroyAllFreeConnections();
                        int mcWrapperListIndex = freePool[j].mcWrapperList.size() - 1;
                        for (int k = mcWrapperListIndex; k >= 0; --k) {
                            MCWrapper mcw = (MCWrapper) freePool[j].mcWrapperList.remove(k);
                            if (!mcw.isMarkedForPurgeDestruction()) {
                                mcw.setPoolState(0);
                                mcw.markForPurgeDestruction();
                                destroyMCWrappeList.add(mcw);
                                --freePool[j].numberOfConnectionsAssignedToThisFreePool;
                            }
                        }
                    }
                } // end free lock
            } //end for j
        } //end syc for destroyMCWrapperListLock
        if (localConnection_ != null) {
            boolean purgeTLS = false;
            /*
             * We can purge connections in the connection pool if we are not in thread sensitive code.
             */
            updateToTLSPoolInProgress.set(true); // set to true for pausing pool.
            synchronized (updateToTLSPoolInProgressLockObject) {
                try {
                    sleep(20);
                } catch (InterruptedException e) {
                }
                if (activeTLSRequest.get() > 0) {
                    try {
                        sleep(100);
                    } catch (InterruptedException e) {
                    }
                    if (activeTLSRequest.get() > 0) {
                        // We can not purge tls
                        if (tc.isDebugEnabled()) {
                            Tr.debug(this, tc, "To many active requests to search tls, active request value is " + activeRequest.get());
                        }
                    } else {
                        purgeTLS = true;
                    }
                } else {
                    purgeTLS = true;
                }
                if (purgeTLS) {
                    if (tc.isDebugEnabled()) {
                        Tr.debug(this, tc, "Searching tls for a connections to purge.");
                    }
                    Iterator<Entry<MCWrapper, ArrayList<MCWrapper>>> it = tlsArrayLists.entrySet().iterator();
                    while (it.hasNext()) {
                        Entry<MCWrapper, ArrayList<MCWrapper>> e = it.next();
                        MCWrapper mcw = e.getKey();
                        if (mcw.getPoolState() == MCWrapper.ConnectionState_freeTLSPool) {
                            ArrayList<MCWrapper> mh = e.getValue();
                            mh.remove(mcw);
                            tlsArrayLists.remove(mcw);
                            if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                                ((com.ibm.ejs.j2c.MCWrapper) mcw).setThreadID(((com.ibm.ejs.j2c.MCWrapper) mcw).getThreadID() + "-purge-removed");
                                Tr.debug(this, tc, "removed mcWrapper from thread local " + mcw);
                            }
                            if (!mcw.isMarkedForPurgeDestruction()) {
                                mcw.setPoolState(0);
                                mcw.markForPurgeDestruction();
                                destroyMCWrappeList.add(mcw);
                            }
                        }
                    }
                }
                updateToTLSPoolInProgress.set(false); // set to false for releasing pool.
                updateToTLSPoolInProgressLockObject.notifyAll();
            }
        }
        /*
         * we need to cleanup and destroy connections in the local destroy list.
         */
        for (int i = 0; i < destroyMCWrappeList.size(); ++i) {
            MCWrapper mcw = destroyMCWrappeList.get(i);
            freePool[0].cleanupAndDestroyMCWrapper(mcw);
            this.totalConnectionCount.decrementAndGet();
        }
        if (tc.isEntryEnabled()) {
            Tr.exit(this, tc, "purgePoolContents");
        }
    }
116250
private void expungeStaleEntries() {
	for (Object x; (x = queue.poll()) != null;) {
	    synchronized (queue) {
		@SuppressWarnings("unchecked")
		Entry<K, V> e = (Entry<K, V>) x;
		int i = indexFor(e.hash, table.length);

		Entry<K, V> prev = table[i];
		Entry<K, V> p = prev;
		while (p != null) {
		    Entry<K, V> next = p.next;
		    if (p == e) {
			if (prev == e) table[i] = next;
			else prev.next = next;
			// Must not null out e.next;
			// stale entries may be in use by a HashIterator
			e.value = null; // Help GC
			size--;
			break;
		    }
		    prev = p;
		    p = next;
		}
	    }
	}
    }
915848
private void dispose(final Throwable cause) {
        assertUnlocked();
        
        lock.lock();
        try {
            if (procThreads == null) {
                // Already disposed
                return;
            }
            for (RequestProcessor processor : procThreads) {
                processor.dispose();
            }
            procThreads = null;
        } finally {
            lock.unlock();
        }

        if (cause == null) {
            fireConnectionClosed();
        } else {
            fireConnectionClosedOnError(cause);
        }

        lock.lock();
        try {
            clearEmptyRequest();
            exchanges = null;
            cmParams = null;
            pendingResponseAcks = null;
            pendingRequestAcks = null;
            notEmpty.signalAll();
            notFull.signalAll();
            drained.signalAll();
        } finally {
            lock.unlock();
        }
        
        httpSender.destroy();
        schedExec.shutdownNow();
    }
949516
public void releaseExternalResources() {

        if (!isClosed.get()) {
            logger.info("Releasing all ParallelClient resources... ");
            ActorConfig.shutDownActorSystemForce();
            httpClientStore.shutdown();
            tcpSshPingResourceStore.shutdown();
            cleanWaitTaskQueue();
            cleanInprogressJobMap();
            isClosed.set(true);
            logger.info("Have released all ParallelClient resources "
                    + "(actor system + async+sync http client + task queue)"
                    + "\nNow safe to stop your application.");

        } else {
            logger.debug("NO OP. ParallelClient resources have already been released.");
        }

    }