/* package whatever; // don't place package name! */
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
class Ideone
{
public static void main
(String[] args
) { /*
Service A 01 03 1
Service B 02 03 2
Service C 03 04 3
Service D 04 05 4
Service E 05 07 5
Service F 06 07 6
Service G 07 (null) 7*/
CallManager manager = new CallManager();
manager.addService(simpleRunnable("A"), "A");
manager.addService(simpleRunnable("B"), "B");
manager.addService(simpleRunnable("C"), "C", "A", "B");
manager.addService(simpleRunnable("D"), "D", "C");
manager.addService(simpleRunnable("E"), "E", "D");
manager.addService(simpleRunnable("F"), "F");
manager.addService(simpleRunnable("G"), "G", "E", "F");
manager.run();
}
// create some simple pseudo service
return () -> {
System.
out.
printf("running service %s%n", s
); try {
Thread.
sleep(RANDOM.
nextInt(2000)); e.printStackTrace();
}
};
}
}
class CallManager {
List<Service> services = new ArrayList<>();
ExecutorService executorService = Executors.newFixedThreadPool(4);
services.add(new Service(r, serviceName, this::preconditionFulfilled, preconditions));
}
void run() {
for (Iterator<Service> serviceIterator = services.iterator(); serviceIterator.hasNext(); ) {
Service service = serviceIterator.next();
if (service.arePreconditionsFulfilled()) {
executorService.submit(service);
serviceIterator.remove();
}
if (services.isEmpty()) {
executorService.shutdown();
}
}
}
private synchronized void preconditionFulfilled
(String name
) { System.
out.
printf("service %s finished%n", name
); for (Iterator<Service> serviceIterator = services.iterator(); serviceIterator.hasNext(); ) {
Service service = serviceIterator.next();
service.preconditionFulfilled(name);
if (service.arePreconditionsFulfilled()) {
executorService.submit(service);
serviceIterator.remove();
}
}
if (services.isEmpty()) {
executorService.shutdown();
}
}
}
private final List<String> preconditions = new CopyOnWriteArrayList<>();
private final Consumer<String> finishedNotification;
this.wrappedRunnable = r;
this.name = name;
this.finishedNotification = finishedNotification;
this.
preconditions.
addAll(Arrays.
asList(preconditions
)); }
@Override
public void run() {
wrappedRunnable.run();
finishedNotification.accept(name);
}
void preconditionFulfilled
(String precondition
) { preconditions.remove(precondition);
}
boolean arePreconditionsFulfilled() {
return preconditions.isEmpty();
}
}