in commons-jcs3-core/src/main/java/org/apache/commons/jcs3/utils/access/JCSWorker.java [204:284]
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();
}
}
}