/*
* polymap.org
* Copyright (C) 2017, the @authors. All rights reserved.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3.0 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.jgrasstools.gears.libs.modules.multiprocessing;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* Submits up to a maximum count tasks to a delegate {@link ExecutorService}. Blocks
* submitting thread if it thries to submit more than the maximum number of tasks.
*
* @author Falko Bräutigam
*/
public class BlockingExecutorService
implements ExecutorService {
private ExecutorService delegate;
private Semaphore taskCount;
/**
*
*
* @param delegate
* @param maxTaskCount The maximum number of tasks to submit to the delegate.
*/
public BlockingExecutorService( ExecutorService delegate, int maxTaskCount ) {
this.delegate = delegate;
this.taskCount = new Semaphore( maxTaskCount );
}
protected void beforeSubmit() {
try {
taskCount.acquire();
}
catch (InterruptedException e) {
throw new RuntimeException( e );
}
}
@Override
public void execute( Runnable command ) {
beforeSubmit();
delegate.execute( () -> {
try {
command.run();
}
finally {
taskCount.release();
}
});
}
@Override
public <T> Future<T> submit( Callable<T> task ) {
beforeSubmit();
return delegate.submit( () -> {
try {
return task.call();
}
finally {
taskCount.release();
}
});
}
@Override
public <T> Future<T> submit( Runnable task, T result ) {
beforeSubmit();
return delegate.submit( () -> {
try {
task.run();
}
finally {
taskCount.release();
}
}, result );
}
@Override
public Future<?> submit( Runnable task ) {
beforeSubmit();
return delegate.submit( () -> {
try {
task.run();
}
finally {
taskCount.release();
}
});
}
@Override
public void shutdown() {
delegate.shutdown();
}
@Override
public List<Runnable> shutdownNow() {
return delegate.shutdownNow();
}
@Override
public boolean isShutdown() {
return delegate.isShutdown();
}
@Override
public boolean isTerminated() {
return delegate.isTerminated();
}
@Override
public boolean awaitTermination( long timeout, TimeUnit unit ) throws InterruptedException {
return delegate.awaitTermination( timeout, unit );
}
@Override
public <T> List<Future<T>> invokeAll( Collection<? extends Callable<T>> tasks ) throws InterruptedException {
// XXX Auto-generated method stub
throw new RuntimeException( "not yet implemented." );
}
@Override
public <T> List<Future<T>> invokeAll( Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit )
throws InterruptedException {
// XXX Auto-generated method stub
throw new RuntimeException( "not yet implemented." );
}
@Override
public <T> T invokeAny( Collection<? extends Callable<T>> tasks ) throws InterruptedException, ExecutionException {
// XXX Auto-generated method stub
throw new RuntimeException( "not yet implemented." );
}
@Override
public <T> T invokeAny( Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit )
throws InterruptedException, ExecutionException, TimeoutException {
// XXX Auto-generated method stub
throw new RuntimeException( "not yet implemented." );
}
}