Today in next part of the series we will talk about How we can release multiple threads via Executor Interface.
As per JAVA 6.0 docs-
<T> List <Future <T> invokeAll (Collection <? Extends Callable <T> tasks) throws InterruptedException
In traditional Java-If we have to release multiple threads-we have to create Thread objects and call
Start method one by one.
In Java 5.0 and above-If we can put all callable objects in a collection object and pass the collection objects to ExecutorService to release.
For example-If we have 1000 thread object to be released, we can create an array list and an ExecutorService object with thread pool size of 20.
// Create an ExecutorService object with thread pool size = 20
// Create an array List with 1000 callable objects.
// Release all threads by ExecutorService.
Some important points to note here are
Ø As ExecutorService has thread pool of 20, it will internally manage queuing and releasing of 1000 threads.
InvokeAll is a blocking method. It means-JVM won't proceed to next line until all the 1000 threads are complete.
All the 1000 threads must have same Return Type <T>.
Ø Future. isDone () is true for each element of the returned list
A completed thread cocould have terminated either normally or by throwing an exception. In both the case return type of Future. isDone () is true.
Ø The results of this method are undefined if the given collection is modified while this operation is in progress
It can throw following exceptions-
InterruptedException-if interrupted while waiting, in which case unfinished tasks are canceled.
NullPointerException-if tasks or any of its elements are null.
RejectedExecutionException-if any task cannot be scheduled for execution.
EXAMPLE-
Imagine a scenario, one needs to write create a txn file of each request coming to system. Following are the requirements-
File name will be the client name.
Ø At a time, almost 1000 clients cocould be connected at a time, so system must be capable of creating 1000 files in one go.
Ø Process of creating one file shocould be less than 5 ms.
Total time of creating all the files shoshould be less than 300 ms.
Let's write the pseudo code for this case-
File creation Thread-implements CALLABLE <Boolean>
// GET the File name and Raw Data in Constructor
Try {
// Create a File Object
// Create a print Writer Object
// Prepare the data and Write in the File
// Close the print Writer and File Object
// Return TRUE
} Catch Exception {
Return FALSE
}
Main Parent Thread
// -- In the Loop for whole Client list ---
Try {
// Create a file creator thread-Pass filename and raw Data
// Add the thread object into an Array List
// Pass the array list to Executor Service interface and invokeAll.
// Loop in the Future <Boolean> and check how many threads completed successfully.
} Catch Exception {
// Take necessary action
} Finally {
// Shut down the ExecutorService
}
Package com. jovialjava. blog. threads;
Import java. io. File;
Import java. io. PrintWriter;
Import java. util .*;
Import java. util. concurrent .*;
// FILE CREATOR THREAD
Class FileTask implements Callable <Boolean> {
Private String name = null;
Private String data = null;
Public FileTask (String name, String data ){
This. name = name;
This. data = data;
}
Public Boolean call (){
Try {
File file = new File (this. name );
PrintWriter writer = new PrintWriter (file );
Writer. write (this. data );
Writer. close ();
Return true;
} Catch (Exception e ){
Return false;
}
}
}
// MAIN THREAD
Public class InvokeAllExample {
Private static final ExecutorService executorPool = Executors. newFixedThreadPool (20 );
Private static final int NO_OF_CLIENT = 1000;
Private static final String FILE_EXT = ". txt ";
Private static String TXN_DATA = "some random txn data for client --> ";
Private static String DIRECTORY = "EXAMPLE" + File. separator;
Static {
If (! New File (DIRECTORY). isDirectory ()){
New File (DIRECTORY). mkdir ();
}
}
Public static void main (String [] args ){
Int success = 0;
Int failure = 0;
/**
* Lets assume we have 1000 clients connected and sending request at
* Time.
*/
Collection <FileTask> collection = new ArrayList <FileTask> ();
For (int I = 0; I <NO_OF_CLIENT; I ++ ){
FileTask task = new FileTask (DIRECTORY + Integer. toString (I) + FILE_EXT, TXN_DATA + I );
Collection. add (task );
}
Long startTime = new Date (). getTime ();
Try {
List <Future <Boolean> list = executorPool. invokeAll (collection );
For (Future <Boolean> fut: list ){
Int ignore = fut. get ()? Success ++: failure ++;
}
} Catch (Exception e ){
E. printStackTrace ();
} Finally {
System. out. println ("total success-" + success );
System. out. println ("total failure-" + failure );
System. out. println ("Total time-" + (new Date (). getTime ()-startTime) + "ms ");
ExecutorPool. shutdown ();
}
} // End of Main
}
Author: silence is gold