/* * Copyright 2008-2009 Xebia and the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package cyrille.util.concurrent; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import com.google.common.base.Function; import com.google.common.util.concurrent.Futures; public class ComposedFutureTest { public void test() throws Exception { final ServiceA serviceA = new ServiceA(); final ServiceB serviceB = new ServiceB(); final ExecutorService executorA = Executors.newFixedThreadPool(2); final ExecutorService executorB = Executors.newFixedThreadPool(2); final InputA inputA = new InputA(); final Future<ResultA> futureResultA = executorA.submit(new Callable<ResultA>() { @Override public ResultA call() throws Exception { return serviceA.work(inputA); } }); final Future<ResultB> futureResultB; String technique = ""; if (technique.equals("serial")) { futureResultB = executorB.submit(new Callable<ResultB>() { @Override public ResultB call() throws Exception { return serviceB.work(futureResultA.get()); } }); } else if (technique.equals("complex")) { Function<ResultA, ResultB> myFunction = new Function<ResultA, ResultB>() { @Override public ResultB apply(final ResultA resultA) { try { Callable<ResultB> myCallable = new Callable<ResultB>() { @Override public ResultB call() throws Exception { return serviceB.work(resultA); } }; return executorB.submit(myCallable).get(); } catch (Exception e) { throw new RuntimeException(); } } }; futureResultB = Futures.compose(futureResultA, myFunction); } else { Function<ResultA, ResultB> myFunction = new Function<ResultA, ResultB>() { @Override public ResultB apply(ResultA from) { return serviceB.work(from); } }; futureResultB = Futures.compose(futureResultA, new AsyncFunction<ResultA, ResultB>(myFunction, executorB)); throw new IllegalStateException(); } System.out.println(futureResultB); } public static class AsyncFunction<F, T> implements Function<F, T> { Function<F, T> function; ExecutorService executor; public AsyncFunction(Function<F, T> function, ExecutorService executor) { super(); this.function = function; this.executor = executor; } public T apply(final F from) { try { Future<T> futureT = executor.submit(new Callable<T>() { @Override public T call() throws Exception { return function.apply(from); } }); return futureT.get(); } catch (Exception e) { throw new RuntimeException(e); } }; } }