Getting a result in the future? - java

I'm looking to get a result from a method which can take a while to complete and doesn't actually return the object, so I'd like to deal with it as effectively as possible. Here's an example of what I'm trying to achieve:
public static void main (String[] args) {
Object obj = someMethod();
System.out.println("The object is" + obj + ", wooh!");
}
public void callObject() {
// Sends request for the object
}
public void receiveObject(Object object) {
// Received the object
}
public Object someMethod() {
callObject();
// delay whilst the object is being received
// return received object once received, but how?
}
The method callObject will call to get the object, however a different method is called with the object in. I want someMethod() to be able to call for the object, and then return what it eventually receives, even though the actual call and receive are separate methods.
I've looked into using FutureTasks and Callables which I think is the way forward, I'm just not too sure how to implement it.
Sorry if I didn't explain myself too well, I'll give more information if necessary.
Thanks!

You could write a method, that kicks of some long running task asynchronously. You would then return a future object, that is empty but gets filled when the long running task is completed. In other programming languages, this is called a promise.
Here is an simple example. I created a method called someLongAsyncOperation which executes something that takes a while. To simulate this, I just sleep for 3 seconds before generating an answer.
import java.util.UUID;
import java.util.concurrent.*;
public class Test {
private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
public Future<MyAnswer> someLongAsyncOperation(){
Future<MyAnswer> future = executorService.submit(() -> {
Thread.sleep(3000);
return new MyAnswer(UUID.randomUUID().toString());
});
return future;
}
public static void main(String[] args) throws Exception {
System.out.println("calling someLongAsyncOperation ...");
Future<MyAnswer> future = new Test().someLongAsyncOperation();
System.out.println("calling someLongAsyncOperation done.");
// do something else
System.out.println("wait for answer ...");
MyAnswer myAnswer = future.get();
System.out.printf("wait for answer done. Answer is: %s", myAnswer.value);
executorService.shutdown();
}
static class MyAnswer {
final String value;
MyAnswer(String value) {
this.value = value;
}
}
}
If you execute this little test class, you'll see, that someLongAsyncOperation returns fast, but when calling future.get(); we wait for the operation to complete.
You could now do something like starting of more than one longAsyncOperation, so they would run in parallel. And then wait until all of them are done.
Does this work as a starting point for you?
EDIT
You could implement someMethod like this:
public MyAnswer someMethod() throws ExecutionException, InterruptedException {
Future<MyAnswer> future = someLongAsyncOperation(); // kick of async operation
return future.get(); // wait for result
}
Which will make the async operation synchron again, by calling it and waiting for the result.
EDIT2
Here's another example that uses wait/notify:
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test2 {
private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
private Object receivedObject;
private final Object mutex = new Object();
public static void main (String[] args) throws InterruptedException {
Object obj = new Test2().someMethod();
System.out.println("The object is" + obj + ", wooh!");
executorService.shutdown();
}
public void callObject() {
System.out.println("callObject ...");
// Sends request for the object asynchronously!
executorService.submit(() -> {
// some wait time to simulate slow request
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// provide object to callback
receiveObject(UUID.randomUUID().toString());
});
System.out.println("callObject done.");
}
public void receiveObject(Object object) {
System.out.println("receiveObject ...");
synchronized (mutex) {
this.receivedObject = object;
mutex.notify();
}
System.out.println("receiveObject done.");
}
public Object someMethod() throws InterruptedException {
System.out.println("someMethod ...");
synchronized (mutex) {
callObject();
while(this.receivedObject == null){
mutex.wait();
}
}
System.out.println("someMethod done.");
return this.receivedObject;
}
}
someMethod waits until receivedObject exists. receiveObject notifies upon arrival.

You need a callback:
private abstract class Callback<T>{
run(T object);
}
public Object someMethod() {
callObject(new Callback<Object>()
{
#Override
public void run(Object object)
{
System.out.println("The object is" + object + ", wooh!");
}
})
}
public void callObject(Callback<Object> callback) {
// Sends request for the object
callback.run(object);
}

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class ThreadExample implements Callable<String>{
#Override
public String call() throws Exception {
// TODO Auto-generated method stub
return "Ashish";
}
}
public class FutureThreadExample {
public static void main(String a[]) throws InterruptedException, ExecutionException {
ExecutorService executorService=Executors.newFixedThreadPool(1);
List <Future<String>>objList=new ArrayList<Future<String>>();
for(int i=0;i<10;i++) {
Future<String> obj=executorService.submit(new ThreadExample());
objList.add(obj);
}
for( Future<String> fut:objList) {
System.out.println(fut.get());
}
executorService.shutdown();
}
}

Related

Java - Thread doesn't want to start

I have this console application, but for some reason the thread's run() method doesn't want to start. The code seems long for the first time but I tried to organize it as much as I can.
The result output:
eThread starting!!
So it seems that CarManager.startFunctionalities() gets executed, but the line eThread.start() is not executed at all because the line "started" is not printed out.
Here is the sourcecode.
The main class:
package rpicar.android;
public class AndroidEmulator{
public static void main(String args[]) throws InterruptedException {
CarManager cm = new CarManager ("localhost");
}
}
CarManager:
package rpicar.android;
import rpicar.common.Direction;
import rpicar.common.EnvironmentData;
public class CarManager {
private MotorManager mManager;
private final String RPIADDRESS = "localhost";
private Thread mThread; //motor
private EnvironmentManager eManager;
private Thread eThread;
public CarManager(String rpiAddress) {
//initialize MotorManager
mManager = new MotorManager(RPIADDRESS);
//Make a thread for the Motor commands
mThread = new Thread(mManager);
//Initialize EnvironmentManager
eManager = new EnvironmentManager(RPIADDRESS);
//Makea thread for collecting EnvironmentData
eThread = new Thread (eThread);
startFunctionalities();
}
public void move(Direction d){
this.mManager.setDirection(d);
}
public EnvironmentData getCurrentEnvironmentData(){
return this.eManager.getCurrentEnvironmentData();
}
private void startFunctionalities(){
//Start MotorManager for sending movement commands when needed.
//mThread.start();
//Start EnvironmentManager to collect EnvironmentData
System.out.println("eThread starting!! ");
eThread.start();
}
}
EnvironmentManager:
package rpicar.android;
import rpicar.common.CarComponent;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import rpicar.common.EnvironmentData;
public class EnvironmentManager extends CarComponent implements Runnable{
private EnvironmentData currentEnvironmentData;
public EnvironmentManager(String rpiAddress) {
super(rpiAddress, 2176, true);
this.currentEnvironmentData = new EnvironmentData();
}
public synchronized EnvironmentData getCurrentEnvironmentData() {
return currentEnvironmentData;
}
public synchronized void setCurrentEnvironmentData(EnvironmentData currentEnvironmentData) {
this.currentEnvironmentData = currentEnvironmentData;
}
#Override
public void run() {
System.out.println("eThread started!! ");
super.connect();
while(true){
try {
this.setCurrentEnvironmentData((EnvironmentData) super.in.readObject());
} catch (IOException ex) {
super.connect();
} catch (ClassNotFoundException ex) {
Logger.getLogger(EnvironmentManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
When you create your instance of eThread, you accidentally pass the thread itself to the constructor (or according to the order of the operations, you pass null).
You should pass eManager to the constructor instead.
eThread = new Thread (eThread);
Would become
eThread = new Thread (eManager);
You can protect yourself in the future from this mistake by making the eThread a final field, so you cannot use it before you declare it.

How to get the output stream from a thread

I currently have several runnable classes, each printing a string upon completion using System.out.println().
In the main() I execute them using a ExecutorService ,executor.execute() for each of them.
I am wondering after executing those threads, how to get the output stream from them for future use ?
Pretty much like using .getInputStream for processes but there's no such method in the Thread class. Thanks!
There's a class which implements runnable interface like this:
public class A implements Runnable {
public void run() {
System.out.println(5); //this thread always print out number 5
}
}
and in the main function I need to get the printed number and store it
public static void main(String[] args) {
ExecutorService ThreadPool = Executors.newFixedThreadPool(1);
ThreadPool.execute(new A()); //This statement will cause the thread object A
//to print out number 5 on the screen
ThreadPool.shutdown();
......
}
Now I need to get the printed number 5 and store it into, say an integer variable.
I think below code will satisfy your requirement.
class MyCallable implements Callable<InputStream>
{
#Override
public InputStream call() throws Exception {
//InputStream inputStreamObject = create object for InputStream
return inputStreamObject;
}
}
class Main
{
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
List<Future<InputStream>> list = new ArrayList<Future<InputStream>>();
for (int i = 0; i < 25; i++) {
Callable<InputStream> worker = new MyCallable();
Future<InputStream> submit = executor.submit(worker);
list.add(submit);
}
InputStream inputStreamObject = null;
for (Future<InputStream> future : list) {
try {
inputStreamObject = future.get();
//use inputStreamObject as your needs
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
}
Runnable and Callable in thread:
runnable interface has a method public abstract void run(); void - which means after completing run method, it will not return anything. Callable<V> interface has a method V call() throws Exception; which means after completing call method, it will return Object V that is parametrized as
public class Run_Vs_Call {
public static void main(String...args){
CallableTask call = new CallableTask();
RunnableTask run = new RunnableTask();
try{
FutureTask<String> callTask = new FutureTask<String>(call);
Thread runTask = new Thread(run);
callTask.run();
runTask.start();
System.out.println(callTask.get());
}catch(Exception e){
e.printStackTrace();
}
}
public static class CallableTask implements Callable<String>{
public String call( ){
String stringObject = "Inside call method..!! I am returning this string";
System.out.println(stringObject);
return stringObject;
}
}
public static class RunnableTask implements Runnable{
public void run(){
String stringObject = "Inside Run Method, I can not return any thing";
System.out.println(stringObject);
}
}
}
you can use new static class:
public class Global{
//example
public static ..
public static ..
}

Parallel Iterator

I've looked through these forums to give me insight on how to create a ParallelIterator, but no luck. I want one Collection to be on one Thread and the another Collection to be on another Thread, but I wish to use a ThreadPool to do the job so that it can split up into parts equal to the amount of cores you have using Runtime.getRuntime().availableProcessors(). I also want to return an Actor rather than a Collection of Actors but the next() method is stopping me from doing so. Here is my code so far:
package com.atem.util;
public class ParallelIterator<Collection<Actor>> implements Iterator<Collection<Actor>> {
private Iterator<Actor> firstActorIterator;
private Iterator<Actor> secondActorIterator;
public ParallelIterator(final Collection<Actor> firstCollection, final Collection<Actor> secondCollection) {
this.firstActorIterator = firstCollection.iterator();
this.secondActorIterator = secondCollection.iterator();
}
#Override
public boolean hasNext() {
return this.getFirstActorIterator().hasNext() && this.getSecondActorIterator().hasNext();
}
#Override
public Collection<Actor> next() {
return new ParallelCollection(this.getFirstActorIterator().next(), this.getSecondActorIterator().next());
}
#Override
public void remove() {
this.getFirstActorIterator().remove();
this.getSecondActorIterator().remove();
}
public Iterator<Actor> getFirstIterator() {
return this.firstIterator;
}
public Iterator<Actor> getSecondIterator() {
return this.secondIterator;
}
public ParallelCollection<Actor> getParallelActorCollection() {
return this.parallelActorCollection;
}
}
I could change the next() method to return an Actor but then the ParallelCollection would get in the way. If there's anything else you wish to know, please let me know. Help is very much appreciated. Also, I'm somewhat of a beginner so if you could explain it in simple terms that would be great. Thanks!
I agree with Louis's comment that you shouldn't try to write something like this on your own, but I wrote something that might help you get started.
WARNING: This code was not thoroughly tested:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Parallel {
//modify the arg for the number of threads you want to use
final static ExecutorService service = Executors.newFixedThreadPool(2);
public static interface Operation<R, E> {
public R perform(E input);
}
public static <R, E> List<R> forEach(final Iterable<E> inputs,
final Operation<R,E> operation) {
final List<Future<R>> futures = Collections.synchronizedList(new ArrayList<Future<R>>());
for (final E input : inputs) {
final Callable<R> callable = new Callable<R>() {
public R call() throws Exception {
return operation.perform(input);
}
};
futures.add(service.submit(callable));
}
final List<R> outputs = new ArrayList<>();
try {
for (final Future<R> future : futures) {
outputs.add(future.get());
}
}
catch (Exception e) {
e.printStackTrace();
}
return outputs;
}
}

Producer-Consumer with Predicate

I'm looking for a java collection that supports blocking read()s on a predicate. I wrote a simple version but it seems like this must have been invented already?
For example:
interface PredicateConsumerCollection<T> {
public void put(T t);
#Nullable
public T get(Predicate<T> p, long millis) throws InterruptedException;
}
put() delivers its argument to a waiting consumer with a matching predicate, or stashes it in a store. A get() returns immediately if a suitable T is already in the store, or blocks till a suitable value is put(), or times out. Consumers compete but fairness isn't critical in my case.
Anyone aware of a such a collection?
There is no immediate class that can solve your problem, but a combination of a ConcurrentHashMap and a BlockingQueue could be a solution.
The hash map is defined as:
final ConcurrentHashMap<Predicate, LinkedBlockingQueue<Result>> lookup;
The put needs to ensure, that for each Predicate a queue is added to the map, this can be done thread-safe using putIfAbsent.
If you have a fixed set of Predicates, you can simply pre-fill the list, then a Consumer can simply call lookup.get(Predicate).take()
If the amount of Predicates is unknown/too many, you need to write a wait/notify implementation for Consumers in case a Predicate is not yet in the list on your own.
I also need something very similar for testing that a certain JMS asynchronous message has been received within a certain timeout. It turns out that your question is relatively easy to implement by using basic wait/notify as explained in the Oracle tutorials. The idea is to make the put and query methods synchronized and let the query method do a wait. The put method calls notifyAll to wake up any waiting threads in the query method. The query method must then check if the predicate is matched. The most tricky thing is getting the timeout right due to waking up when the predicate does not match and due to possible " spurious wakeups". I found this stackoverflow post that provides the answer.
Here is the implementation I came up with:
import java.util.ArrayList;
import java.util.List;
// import net.jcip.annotations.GuardedBy;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
public class PredicateConsumerCollectionImpl<T> implements
PredicateConsumerCollection<T> {
// #GuardedBy("this")
private List<T> elements = new ArrayList<>();
#Override
public synchronized void put(T t) {
elements.add(t);
notifyAll();
}
#Override
public synchronized T query(Predicate<T> p, long millis)
throws InterruptedException {
T match = null;
long nanosOfOneMilli = 1000000L;
long endTime = System.nanoTime() + millis * nanosOfOneMilli;
while ((match = Iterables.find(elements, p, null)) == null) {
long sleepTime = endTime - System.nanoTime();
if (sleepTime <= 0) {
return null;
}
wait(sleepTime / nanosOfOneMilli,
(int) (sleepTime % nanosOfOneMilli));
}
return match;
}
synchronized boolean contains(T t) {
return elements.contains(t);
}
}
And here is a JUnit test that proves that the code works as intended:
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Before;
import org.junit.Test;
import com.google.common.base.Predicate;
/**
* Unit test for the {#link PredicateConsumerCollection} implementation.
*
* <p>
* The tests act as consumers waiting for the test Producer to put a certain
* String.
*/
public class PredicateConsumerCollectionTest {
private static class Producer implements Runnable {
private PredicateConsumerCollection<String> collection;
public Producer(PredicateConsumerCollection<String> collection) {
this.collection = collection;
collection.put("Initial");
}
#Override
public void run() {
try {
int millis = 50;
collection.put("Hello");
Thread.sleep(millis);
collection.put("I");
Thread.sleep(millis);
collection.put("am");
Thread.sleep(millis);
collection.put("done");
Thread.sleep(millis);
collection.put("so");
Thread.sleep(millis);
collection.put("goodbye!");
} catch (InterruptedException e) {
e.printStackTrace();
fail("Unexpected InterruptedException");
}
}
}
private PredicateConsumerCollectionImpl<String> collection;
private Producer producer;
#Before
public void setup() {
collection = new PredicateConsumerCollectionImpl<>();
producer = new Producer(collection);
}
#Test(timeout = 2000)
public void wait_for_done() throws InterruptedException {
assertTrue(collection.contains("Initial"));
assertFalse(collection.contains("Hello"));
Thread producerThread = new Thread(producer);
producerThread.start();
String result = collection.query(new Predicate<String>() {
#Override
public boolean apply(String s) {
return "done".equals(s);
}
}, 1000);
assertEquals("done", result);
assertTrue(collection.contains("Hello"));
assertTrue(collection.contains("done"));
assertTrue(producerThread.isAlive());
assertFalse(collection.contains("goodbye!"));
producerThread.join();
assertTrue(collection.contains("goodbye!"));
}
#Test(timeout = 2000)
public void wait_for_done_immediately_happens() throws InterruptedException {
Thread producerThread = new Thread(producer);
producerThread.start();
String result = collection.query(new Predicate<String>() {
#Override
public boolean apply(String s) {
return "Initial".equals(s);
}
}, 1000);
assertEquals("Initial", result);
assertFalse(collection.contains("I"));
producerThread.join();
assertTrue(collection.contains("goodbye!"));
}
#Test(timeout = 2000)
public void wait_for_done_never_happens() throws InterruptedException {
Thread producerThread = new Thread(producer);
producerThread.start();
assertTrue(producerThread.isAlive());
String result = collection.query(new Predicate<String>() {
#Override
public boolean apply(String s) {
return "DONE".equals(s);
}
}, 1000);
assertEquals(null, result);
assertFalse(producerThread.isAlive());
assertTrue(collection.contains("goodbye!"));
}
}

How to know when a CompletionService is finished delivering results?

I want to use a CompletionService to process the results from a series of threads as they are completed. I have the service in a loop to take the Future objects it provides as they become available, but I don't know the best way to determine when all the threads have completed (and thus to exit the loop):
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
public class Bar {
final static int MAX_THREADS = 4;
final static int TOTAL_THREADS = 20;
public static void main(String[] args) throws Exception{
final ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(MAX_THREADS);
final CompletionService<Integer> service = new ExecutorCompletionService<Integer>(threadPool);
for (int i=0; i<TOTAL_THREADS; i++){
service.submit(new MyCallable(i));
}
int finished = 0;
Future<Integer> future = null;
do{
future = service.take();
int result = future.get();
System.out.println(" took: " + result);
finished++;
}while(finished < TOTAL_THREADS);
System.out.println("Shutting down");
threadPool.shutdown();
}
public static class MyCallable implements Callable<Integer>{
final int id;
public MyCallable(int id){
this.id = id;
System.out.println("Submitting: " + id);
}
#Override
public Integer call() throws Exception {
Thread.sleep(1000);
System.out.println("finished: " + id);
return id;
}
}
}
I've tried checking the state of the ThreadPoolExecutor, but I know the getCompletedTaskCount and getTaskCount methods are only approximations and shouldn't be relied upon. Is there a better way to ensure that I've retrieved all the Futures from the CompletionService than counting them myself?
Edit: Both the link that Nobeh provided, and this link suggest that counting the number of tasks submitted, then calling take() that many times, is the way to go. I'm just surprised there isn't a way to ask the CompletionService or its Executor what's left to be returned.
See http://www.javaspecialists.eu/archive/Issue214.html for a decent suggestion on how to extend the ExecutorCompletionService to do what you're looking for. I've pasted the relevant code below for your convenience. The author also suggests making the service implement Iterable, which I think would be a good idea.
FWIW, I agree with you that this really should be part of the standard implementation, but alas, it's not.
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
public class CountingCompletionService<V> extends ExecutorCompletionService<V> {
private final AtomicLong submittedTasks = new AtomicLong();
private final AtomicLong completedTasks = new AtomicLong();
public CountingCompletionService(Executor executor) {
super(executor);
}
public CountingCompletionService(
Executor executor, BlockingQueue<Future<V>> queue) {
super(executor, queue);
}
public Future<V> submit(Callable<V> task) {
Future<V> future = super.submit(task);
submittedTasks.incrementAndGet();
return future;
}
public Future<V> submit(Runnable task, V result) {
Future<V> future = super.submit(task, result);
submittedTasks.incrementAndGet();
return future;
}
public Future<V> take() throws InterruptedException {
Future<V> future = super.take();
completedTasks.incrementAndGet();
return future;
}
public Future<V> poll() {
Future<V> future = super.poll();
if (future != null) completedTasks.incrementAndGet();
return future;
}
public Future<V> poll(long timeout, TimeUnit unit)
throws InterruptedException {
Future<V> future = super.poll(timeout, unit);
if (future != null) completedTasks.incrementAndGet();
return future;
}
public long getNumberOfCompletedTasks() {
return completedTasks.get();
}
public long getNumberOfSubmittedTasks() {
return submittedTasks.get();
}
public boolean hasUncompletedTasks() {
return completedTasks.get() < submittedTasks.get();
}
}
The code below is inspired by #Mark's answer, but I find it more convenient to use:
package com.example;
import java.util.Iterator;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class CompletionIterator<T> implements Iterator<T>, AutoCloseable {
private AtomicInteger count = new AtomicInteger(0);
private CompletionService<T> completer;
private ExecutorService executor = Executors.newWorkStealingPool(100);
public CompletionIterator() {
this.completer = new ExecutorCompletionService<>(executor);
}
public void submit(Callable<T> task) {
completer.submit(task);
count.incrementAndGet();
}
#Override
public boolean hasNext() {
return count.decrementAndGet() >= 0;
}
#Override
public T next() {
try {
return completer.take().get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
#Override
public void close() {
try {
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
executor = null;
completer = null;
count = null;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
This is how it can be used :
try(CompletionIterator service = new CompletionIterator()) {
service.submit(task1);
service.submit(task2);
// all tasks must be submitted before iterating, to avoid race condition
for (Future<Integer> future : service) {
System.out.printf("Job %d is done%n", future.get());
}
}
Answering to these questions gives you the answer?
Do your asynchronous tasks create other tasks submitted to CompletionService?
Is service the only object that is supposed to handle the tasks created in your application?
Based on reference documentation, CompletionService acts upon a consumer/producer approach and takes advantage of an internal Executor. So, as long as, you produce the tasks in one place and consume them in another place, CompletionService.take() will denote if there are any more results to give out.
I believe this question also helps you.
My take based on Alex R' variant. Implying this will only be called in one thread, so no atomics just plain int counter
public class CompletionIterator<T> implements Iterable<T> {
private int _count = 0;
private final CompletionService<T> _completer;
public CompletionIterator(ExecutorService executor) {
this._completer = new ExecutorCompletionService<>(executor);
}
public void submit(Callable<T> task) {
_completer.submit(task);
_count++;
}
#Override
public Iterator<T> iterator() {
return new Iterator<T>() {
#Override
public boolean hasNext() {
return _count > 0;
}
#Override
public T next() {
try {
T ret = _completer.take().get();
_count--;
return ret;
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
};
}
}

Categories

Resources