private V run()

in commons-jcs3-core/src/main/java/org/apache/commons/jcs3/utils/access/JCSWorker.java [203:283]


    private V run( final K aKey, final String aGroup, final JCSWorkerHelper<V> aHelper )
        throws Exception
    {
        V result = null;
        // long start = 0;
        // long dbTime = 0;
        final JCSWorkerHelper<V> helper = map.putIfAbsent(getRegion() + aKey, aHelper);

        if ( helper != null )
        {
            synchronized ( helper )
            {
                logger.debug( "Found a worker already doing this work ({0}:{1}).",
                        this::getRegion, () -> aKey );
                while ( !helper.isFinished() )
                {
                    try
                    {
                        helper.wait();
                    }
                    catch (final InterruptedException e)
                    {
                        // expected
                    }
                }
                logger.debug( "Another thread finished our work for us. Using "
                        + "those results instead. ({0}:{1}).",
                        this::getRegion, () -> aKey );
            }
        }
        // Do the work
        try
        {
            logger.debug( "{0} is doing the work.", this::getRegion);

            // Try to get the item from the cache
            if ( aGroup != null )
            {
                result = groupCache.getFromGroup( aKey, aGroup );
            }
            else
            {
                result = cache.get( aKey );
            }
            // If the cache doesn't have it, do the work.
            if ( result == null )
            {
                result = aHelper.doWork();
                logger.debug( "Work Done, caching: key:{0}, group:{1}, result:{2}.",
                        aKey, aGroup, result );
                // Stick the result of the work in the cache.
                if ( aGroup != null )
                {
                    groupCache.putInGroup( aKey, aGroup, result );
                }
                else
                {
                    cache.put( aKey, result );
                }
            }
            // return the result
            return result;
        }
        finally
        {
            logger.debug( "{0}:{1} entered finally.", this::getRegion,
                    () -> aKey );

            // Remove ourselves as the worker.
            if ( helper == null )
            {
                map.remove( getRegion() + aKey );
            }
            synchronized ( aHelper )
            {
                aHelper.setFinished( true );
                // Wake everyone waiting on us
                aHelper.notifyAll();
            }
        }
    }