base/common/src/main/com/thesett/common/util/TimeoutMap.java
private void sweep()
    {
        /*log.fine("private void sweep(): called");*/

        // Loop until the thread is terminated.
        while (true)
        {
            // Take a marked copy of the cache to examine for timed out elements.
            // Synchronize on the cache to ensure its integrity in a multi-threaded environment.
            synchronized (cache)
            {
                /*log.fine("\tMarking " + cache.size() + " objects.");*/

                // Take a copy of everything in the cache into the marked heap.
                marked.putAll(cache);
            }

            // Use synchronized block to own this objects monitor so that it can be waited on.
            // This is needed so that the kill method, and other methods, can wake this thread up.
            synchronized (this)
            {
                // Use a try block as the thread may be woken up during the pause time between sweeps.
                try
                {
                    // Halt the thread between sweeps, configured by the sweepTime property.
                    wait(sweepTime);
                }
                catch (InterruptedException e)
                {
                    // Ignore this, interuption conditions will be tested later.
                }
            }

            // TODO: Should really check that sweepTime has expired.

            // Check the sweep thread kill flag to see if the sweep algorithm has been stopped.
            if (sweepThreadKillFlag)
            {
                return;
            }

            // Create a counter to count the number of elements removed from the cache.
            int i = 0;

            // Create a map to copy the marked heap into. This is done because the following code must iterate
            // over the marked heap whilst modifying it. A copy is used to generate all the keys to iterate over so
            // that the iterator is not disturbed by its underlying data structure being simultaneously modified.
            Map copy = new HashMap();

            // Synchronize on the cache to ensure its integrity in a multi-threaded environment.
            synchronized (cache)
            {
                // Put everything in the marked cache into the copy.
                copy.putAll(marked);
            }

            // Loop over the copy of the marked heap looking for timed out elements.
            for (Object nextKey : copy.keySet())
            {
                // Get the key of the next element from the copy of the marked heap.
                // Extract the current element from the copy of the marked heap as an ElementMonitor object.
                ElementMonitor nextMonitor = (ElementMonitor) copy.get(nextKey);

                // Get the current time in milliseconds.
                long t = System.currentTimeMillis();

                // Check if the current element has not been accessed for a while, configured by the
                // sweepExpiryTime property.
                if ((t - nextMonitor.lastTouched) > sweepExpiryTime)
                {
                    // Synchronize on the cache to ensure its integrity in a multi-threaded environment.
                    synchronized (cache)
                    {
                        // Remove the out of date element from the marked heap and from the cache.
                        marked.remove(nextKey);
                        cache.remove(nextKey);

                        /*log.fine("Element removed from the cache " + nextKey);*/

                        // Increment the count of invalidated elements.
                        i++;

                    }
                }
            }

            /*log.fine(i + " objects removed.");*/
        }
    }
private void sweep()
    {
        /*log.fine("private void sweep(): called");*/

        // Loop until the thread is terminated.
        while (true)
        {
            // Take a marked copy of the cache to examine for timed out elements.
            // Synchronize on the cache to ensure its integrity in a multi-threaded environment.
            synchronized (cache)
            {
                /*log.fine("\tMarking " + cache.size() + " objects.");*/

                // Take a copy of everything in the cache into the marked heap.
                marked.putAll(cache);
            }

            // Use synchronized block to own this objects monitor so that it can be waited on.
            // This is needed so that the kill method, and other methods, can wake this thread up.
            synchronized (this)
            {
                // Use a try block as the thread may be woken up during the pause time between sweeps.
                try
                {
                    // Halt the thread between sweeps, configured by the sweepTime property.
                    wait(sweepTime);
                }
                catch (InterruptedException e)
                {
                    // Ignore this, interuption conditions will be tested later.
                }
            }

            // TODO: Should really check that sweepTime has expired.

            // Check the sweep thread kill flag to see if the sweep algorithm has been stopped.
            if (sweepThreadKillFlag)
            {
                return;
            }

            // Create a counter to count the number of elements removed from the cache.
            int i = 0;

            // Create a map to copy the marked heap into. This is done because the following code must iterate
            // over the marked heap whilst modifying it. A copy is used to generate all the keys to iterate over so
            // that the iterator is not disturbed by its underlying data structure being simultaneously modified.
            Map copy = new HashMap();

            // Synchronize on the cache to ensure its integrity in a multi-threaded environment.
            synchronized (cache)
            {
                // Put everything in the marked cache into the copy.
                copy.putAll(marked);
            }

            // Loop over the copy of the marked heap looking for timed out elements.
            for (Object nextKey : copy.keySet())
            {
                // Get the key of the next element from the copy of the marked heap.
                // Extract the current element from the copy of the marked heap as an ElementMonitor object.
                ElementMonitor nextMonitor = (ElementMonitor) copy.get(nextKey);

                // Get the current time in milliseconds.
                long t = System.currentTimeMillis();

                // Check if the current element has not been accessed for a while, configured by the
                // sweepExpiryTime property.
                if ((t - nextMonitor.lastTouched) > sweepExpiryTime)
                {
                    // Synchronize on the cache to ensure its integrity in a multi-threaded environment.
                    synchronized (cache)
                    {
                        // Remove the out of date element from the marked heap and from the cache.
                        marked.remove(nextKey);
                        cache.remove(nextKey);

                        /*log.fine("Element removed from the cache " + nextKey);*/

                        // Increment the count of invalidated elements.
                        i++;

                    }
                }
            }

            /*log.fine(i + " objects removed.");*/
        }
    }
Garbage collects the cache, sweeping out any elements that have timed out. This method should really only be
invoked in a seperate thread as it does not return (at least not until the {@link #sweepThreadKillFlag} is set).

@todo Should really check that the sweep time has actually expired when the thread wakes up.