Quantcast
Channel: Learning the code way
Viewing all articles
Browse latest Browse all 231

And They All Work Together

$
0
0
In the previous post we had a look at the invokeAny method that allowed us to get the result from the first thread to complete. ExecutorService also provides us with the invokeAll method that will execute all the tasks given. Consider the below code:

publicclass InvokeAllEg {
privatestatic Random random = new Random((long)Math.random() * 3);

privatestaticint getProblemInput() {
int nxtNo = random.nextInt();
nxtNo = nxtNo < 0 ? nxtNo * -1 : nxtNo;
return nxtNo/1000; //just reducing the size of number
}

publicstaticvoid main(String[] args) throws InterruptedException,
ExecutionException {
finalint PARTICIPANT_COUNT = 5;
Collection<Participant> participants = new ArrayList<Participant>(PARTICIPANT_COUNT);

for (int i = 0; i < PARTICIPANT_COUNT; i++) {
Participant participant = new Participant(getProblemInput());
participants.add(participant);
}
System.out.println("Start solving ..");
ExecutorService executorService = Executors.newFixedThreadPool(PARTICIPANT_COUNT);
try {
List<Future<Long>> solutionParts = executorService.invokeAll(participants);
long result = 0;
for (Future<Long> solutionPart : solutionParts) {
if (!solutionPart.isCancelled()) {
result = result + solutionPart.get().longValue();
} else {
System.out.println("Sub Task cancelled");
}
}
System.out.println("Complete solution has been found , result is " + result);
} finally {
executorService.shutdown();
}
}
}
In the above code we have divided our Input problem into various parts and handed each part to a Participant instance. The invokeAll method takes the collection of these Callables and retuns a Collection of Futures. As per the method's documentation:
Executes the given tasks, returning a list of Futures holding their status and 
results when all complete.
Future.isDone is true for each element of the returned
list. Note that a completed task could have terminated either normally or by
throwing an exception.
The results of this method are undefined if the given collection
is modified while this operation is in progress.
As seen we have checked the isCancelled flag for each future to see if a successful result was available, before we used it. The invokeAll method blocks until processing of all tasks is complete before returning.The Participant class is as below:
class Participant implements Callable<Long> {

privateint problemPiece;

public Participant(int problem) {
this.problemPiece = problem;
}

@Override
public Long call() throws Exception {
String threadName = "[" + Thread.currentThread().getName() + "]";
//Start processing
System.out.println(threadName + " working with " + problemPiece);
long result = 0;
for (long i = 0; i < problemPiece; i++) {
if (Thread.interrupted()) {
System.out.println("Interrupt request received at " + threadName + " to cancel");
thrownew InterruptedException();
}
result = result + 1;
}
System.out.println("Result computed by " + threadName + " is - " + result);
return Long.valueOf(result);
}

}
On execution :
Start solving ..
[pool-1-thread-1] working with 1155484
[pool-1-thread-3] working with 1033096
[pool-1-thread-2] working with 723955
[pool-1-thread-4] working with 1690734
[pool-1-thread-5] working with 1557280
Result computed by [pool-1-thread-2] is - 723955
Result computed by [pool-1-thread-4] is - 1690734
Result computed by [pool-1-thread-3] is - 1033096
Result computed by [pool-1-thread-1] is - 1155484
Result computed by [pool-1-thread-5] is - 1557280
Complete solution has been found , result is 6160549
As seen the solution was formed from the result of tasks executed by all the threads. Similar to invokeAny, there is an overloaded method that could be used:
List<Future<Long>> solutionParts = executorService.invokeAll(participants, 300l, TimeUnit.MILLISECONDS);

Viewing all articles
Browse latest Browse all 231

Trending Articles