try { List<Future<?>> futures = new ArrayList<Future<?>>(); // kick off several async tasks futures.add(executor.submit(new CallToRemoteServiceA())); futures.add(executor.submit(new CallToRemoteServiceB())); futures.add(executor.submit(new CallToRemoteServiceC("A"))); futures.add(executor.submit(new CallToRemoteServiceC("B"))); futures.add(executor.submit(new CallToRemoteServiceC("C"))); futures.add(executor.submit(new CallToRemoteServiceD(1))); futures.add(executor.submit(new CallToRemoteServiceE(2))); futures.add(executor.submit(new CallToRemoteServiceE(3))); futures.add(executor.submit(new CallToRemoteServiceE(4))); futures.add(executor.submit(new CallToRemoteServiceE(5))); // as each completes do further work // keep polling until all work is done while (futures.size() > 0) { // use an iterator so we can remove from it Iterator<Future<?>> i = futures.iterator(); while (i.hasNext()) { Future<?> f = i.next(); if (f.isDone()) { // only do work if the Future is done doMoreWork(f.get()); i.remove(); } // otherwise we continue to the next Future } } } finally { executor.shutdownNow(); }
try { List<Future<?>> futures = new ArrayList<Future<?>>(); // kick off several async tasks futures.add(executor.submit(new CallToRemoteServiceA())); futures.add(executor.submit(new CallToRemoteServiceB())); futures.add(executor.submit(new CallToRemoteServiceC("A"))); futures.add(executor.submit(new CallToRemoteServiceC("B"))); futures.add(executor.submit(new CallToRemoteServiceC("C"))); futures.add(executor.submit(new CallToRemoteServiceD(1))); futures.add(executor.submit(new CallToRemoteServiceE(2))); futures.add(executor.submit(new CallToRemoteServiceE(3))); futures.add(executor.submit(new CallToRemoteServiceE(4))); futures.add(executor.submit(new CallToRemoteServiceE(5))); // as each completes do further work // keep polling until all work is done while (futures.size() > 0) { // use an iterator so we can remove from it Iterator<Future<?>> i = futures.iterator(); while (i.hasNext()) { Future<?> f = i.next(); if (f.isDone()) { // only do work if the Future is done doMoreWork(f.get()); i.remove(); } // otherwise we continue to the next Future } } } finally { executor.shutdownNow(); }
away from boiler plate code to focus on business logic. •Abstracts away from low-level threading, synchronization, and concurrency issues. •Stream processing implies memory efficient. •The model can be applied almost everywhere to solve almost any kind of problem.
once can be subscribed to many times Stream#parallel() splits sequence into partitions (Spliterator) do not split data Stream#parallel() by default doesn't allow to specify thread pool to use uses Schedulers
the given Observer to this ObservableSource instance public final Disposable subscribe(Observer<? super T> observer); } public interface Observer<T> { void onSubscribe(Disposable d); void onNext(T value); void onError(Throwable e); void onComplete(); }
the given Observer to this ObservableSource instance void subscribe(Observer<? super T> observer); // factory methods public static <T> Observable<T> just(T item); public static <T> Observable<T> fromIterable(Iterable<? extends T> source); // intermediate operations public final <R> Observable<R> map(Function<? super T, ? extends R> mapper); // debug methods public final Observable<T> doOnError(Consumer<? super Throwable> onError); }
as Observable public final Flowable<T> onBackpressureBuffer(); public final Flowable<T> onBackpressureDrop(); public final Flowable<T> onBackpressureLatest() }