Parallel threading in Java - java

Ok, so I'm trying to find the maximum element of a 2D array. I will have a method that accepts the 2darray as a parameter and finds the maximum. It needs to find the maximum element of each row as a separate thread so that the threads run parrallel, then join each thread, and finding the max of those to get the maximum of the entire 2d array. Now the problem I'm having is that run() does not return any value...How then am i supposed to access the value that has been modified. for example
public static int maxof2darray(long[][] input){
ArrayList<Thread> threads = new ArrayList<Thread>();
long[]rowArray;
for(int i=0; i<input.length; i++){
rowArray = input[i];
teste r1 = new teste(rowArray,max);
threads.add(new Thread(r1));
}
for ( Thread x : threads )
{
x.start();
}
try {
for ( Thread x : threads)
{
x.join();
}
}
as you can see it creates an arraylist of thread objects. Then takes each row and calls the run() function that finds the maximum of that row...the problem is run() does not return any value...How then can i possibly access the maximum of that row?

The Future API should do what you need.
A Future represents the result of an
asynchronous computation. Methods are
provided to check if the computation
is complete, to wait for its
completion, and to retrieve the result
of the computation. The result can
only be retrieved using method get
when the computation has completed,
blocking if necessary until it is
ready. Cancellation is performed by
the cancel method. Additional methods
are provided to determine if the task
completed normally or was cancelled.
Once a computation has completed, the
computation cannot be cancelled. If
you would like to use a Future for the
sake of cancellability but not provide
a usable result, you can declare types
of the form Future and return null
as a result of the underlying task.

I think this is not proper way for starting and joining the threads. You should use Thread Pool instead.
Following is a sample of code that demonstrates Thread Pool.
ExecutorService workers = Executors.newFixedThreadPool(10);
for(int i=0; i<input.length; i++) {
Teste task = new Teste(rowArray,max);
workers.execute(task);
}
workers.shutdown();
while(!workers.isTerminated()) {
try {
Thread.sleep(10000);
} catch (InterruptedException exception) {
}
System.out.println("waiting for submitted task to finish operation");
}
Hope this help.

Unless the array is fairly large it will be faster to do the search in one thread. However say the size is 1000s or more I suggest you use the ExecutionService which is a simple way to manage tasks.
However, the simplest change is to store the result in an AtomicLong, that way your Runnables don't need to return a result.

You can add a new field to your "teste" class that holds the max row. The main thread stops at x.join(), so after that line to can refer to that field and get the max value.
.
.
.
int max=0;
for ( Thread x : threads)
{
x.join();
max=x.getMax();
}
.
.
.

Related

Parallel Processing of DTO in Java 7

I have requirement where need to process and map the DTOs with the values in for loop as below. Each of the mapping method here consumes nearly 10 minutes to complete its business logic and hence creating performance delay. I am working to refine the algorithms of business logic. However, please let me know if each of these mapping methods can be parallel processed to increase performance.
Since application is compatible only with Java 7 I cannot use streams of java 8.
for(Portfolio pf : portfolio) {
mapAddress(pf);
mapBusinessUnit(pf);
mapRelationShipDetails(pf)
--
--
--
}
You could split portfolios to different threads using either Runnable or Callable.
For example:
public class PortfolioService implements Callable<List<Portfolio>>
{
List<Portfolio> portfolios;
public PortfolioService(List<Portfolio> portfolios)
{
this.portfolios = portfolios;
}
public List<Portfolio> call()
{
for(Portfolio pf : portfolios) {
mapAddress(pf);
mapBusinessUnit(pf);
...
}
return portfolios;
}
}
However, this needs some modifications in your main class. I am using Callable here, since I don't know if you want to do something with all of these mapped Portfolios afterwards. However, if you want to let the threads do all of the work and don't need any return, use Runnable and modify the code.
1) You have to get your amount of cores:
int threads = Runtime.getRuntime().availableProcessors();
2) Now you split the workload per thread
// determine the average workload per thread
int blocksize = portfolios.size()/threads;
// doesn't always get all entries
int overlap = portfolios.size()%threads;
3) Start an ExecutorService, make a list of Future Elements, make reminder variable for old index of array slice
ExecutorService exs = Executors.newFixedThreadPool(threads);
List<Future<List<Portfoilio>>> futures = new ArrayList();
int oldIndex = 0;
4) Start threads
for(int i = 0; i<threads; i++)
{
int actualBlocksize = blocksize;
if(overlap != 0){
actualBlocksize++;
overlap--;
}
futures.add(exs.submit(new PortfolioService(portfolios.subList(oldIndex,actualBlocksize));
oldIndex = actualBlocksize;
}
5) Shutdown the ExecutorService and await it's termination
exs.shutdown();
try {exs.awaitTermination(6, TimeUnit.HOURS);}
catch (InterruptedException e) { }
6) do something with the future, if you want / have to.

is my ExecutorService Implementation Correct?

I am new to Multithreading and I am trying make my program faster using ExecutorService. Below is y implementation but, my program is still not working fast. Can you please look at my code and advise?
It basically reads the list of email addresses and stores in the ArrayList. I use the ExecutorService and loop through the ArrayList and call a Callable class does some processing and returns a Boolean.
ArrayList<String> emailAddressList = new ArrayList<>();
ExecutorService executor = Executors.newFixedThreadPool(7);
for (int i = 0; i < emailAddressList.size(); i++) {
Future<Boolean> resultFromThread = executor.submit(new Verify(emailAddressList.get(i)));
bufferedWriter.write(emailAddressList.get(i) + "|" + resultFromThread.get());
bufferedWriter.newLine();
}
executor.shutdown();
executor.awaitTermination(3, TimeUnit.SECONDS);
===========================================================================
public class Verify implements Callable<Boolean> {
private String email;
public Verify(String email) {
this.email = email;
}
#Override
public Boolean call() throws Exception {
Boolean result = false;
try {
result = Validator2.isAddressValid(email);
} catch (Exception e) {
}
return result;
}
}
In each iteration of the loop, two actions are performed:
A Callable is scheduled to run with the Executor
Immediately after that - yet before another task is scheduled - the code waits for the Executor to complete the Callable just submitted.
That way, all Callables are still executed in a serial fashion (we wait to complete one before we submit another), rather than executing them in parallel.
A simple solution might be to submit all callables for execution first. Then, in a separate loop, the wait for them to complete and to process the results. That way, the performance shall improve because of parallel processing of the Callables.
Example:
List<Future<Boolean>> futures ... ;
for (int i = 0; i < emailAddressList.size(); i++) {
futures.add(executor.submit(new Verify(emailAddressList.get(i))));
}
for (int i = 0; i < emailAddressList.size(); i++)
bufferedWriter.write(emailAddressList.get(i) + "|" + futures.get(i).get());
bufferedWriter.newLine();
}
Note that this code waits for the Callables to complete in the order they were submitted to the Executor. This may not necesarily be the case. If the order of the adresses in the resulting writer is not important, one may consider a completely asychronous processing. In Java 8, this can be achieved e.g using the CompleteableFuture API.
You have effectively made your code synchronous and single-threaded without offering any advantage to using a threaded executor. When calling resultFromThread.get(), it will block the main thread and will prevent the next loop iteration that submits the next Task to execute from running until the previous one completes. If you want the submitted Verify tasks to run concurrently, you should submit all of the tasks first in one loop appended to a List<Future<Boolean>>. Then, in another loop, you can iterate through each of those and then call .get(), such that the main thread will await completion of all executions, but won't stop the 7 other threads from executing concurrently.

Java Thread Pool Timing Issue

I'm trying to use a thread pool to execute some code, however I'm having some trouble getting it to run without errors.
Here is my current structure:
while (!(queue.IsEmpty()))
{
currentItem= queue.GetNextItem();
for (int i = 0; i < currentItem.destinations.GetNoOfItems(); i++) //for each neighbor of currentItem
{
threadPool.submit(new NeighbourThread(currentItem, allVertices, routetype, pqOpen, i, endLocation));
}
//threadPool.shutdown();
}
NeighbourThread class:
public class NeighbourThread implements Runnable {
Vertex tempVertex, endLocation;
VertexHashMap allVertices;
int routetype, i;
PriorityQueue pqOpen;
public NeighbourThread(Vertex tempVertex, VertexHashMap allVertices, int routetype, PriorityQueue pqOpen, int i, Vertex endLocation)
{
...variables
}
#Override
public void run() {
...execution code
}
}
My idea is that it will create the amount of threads required based on currentItem.destinations.GetNoOfItems()(as it reuses threads, I'm assuming if it reaches the limit on thread creation it will wait for a thread to finish execution and reuse it).
Once the threads have been allocated, it will submit each runnable to the thread and start it.
However I need my program to wait for all threads to finish execution before it loops back to the while loop.
After reading the documentation on .shutdown(), I think that stops any future use of the threadpool, which I'm guessing is why I get this error:
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask#3d4eac69 rejected from java.util.concurrent.ThreadPoolExecutor#42a57993[Shutting down, pool size = 3, active threads = 1, queued tasks = 0, completed tasks = 3]
I'm trying to improve execution time on my program and as I'm currently doing over 1.5 million invocations of what will be in the run() method, I feel this will help.
So is there anyway to get the program to wait until the threads have finished before continuing with the while loop?
The easiest solution is to use the Futures to notify you when they have completed. Unfortunately, Java does not support listenable Futures out of the box, but you can use the Guava library to supplement you here.
Guava adds the ListeneableFuture, which you can make using the Futures utility class:
ListeningExecutorService executor = MoreExecutors.listeningDecorator(threadPool);
// Collect the futures as you add them to the threadpool
List<ListenableFuture<?>> futures = new ArrayList<>();
while (! queue.IsEmpty())
{
currentItem = queue.GetNextItem();
for (int i = 0; i < currentItem.destinations.GetNoOfItems(); i++)
{
// NeighbourThread should be a Runnable and not a Thread!
futures.add(executor.submit(new NeighbourThread(currentItem, allVertices, routetype, pqOpen, i, endLocation)));
}
}
// Get notified when they're all done (doesn't imply success!)
Futures.allAsList(futures)).addListener(new Runnable() {
// When this callback is executed, then everything has finished
}, MoreExecutors.directExecutor());
Alternatively, you could do this with a CountdownLatch if you know how many items you need to run upfront.

Java Threading: Futures only using results from first and last thread

I have a simple utility which pings a set of nodes and returns an ArrayList of strings to a future object to be outputted to a file. The program should run until terminated by the user.
It doesn't appear that the future receives the results (or at least passes them to the method to output to the file). No matter the number of threads I have concurrently running (always less than 100, determined by an input file), I am only outputting the results from the first and last initialized threads.
As a sanity check, I created a global variable in which each thread will send its results before closing and returning its results to the Future object. This variable is correctly updated by all threads.
Does anyone have any ideas why Future doesn't seem to be receiving all my results from the threads?
public class PingUtility{
public static ExecutorService pool = Executors.newFixedThreadPool(100);
static Future<ArrayList<String>> future;
public static void main(String[] args) throws Exception {
Timer timer = new Timer();
TimerTask task = new TimerTask(){
public void run(){
//Creates a pool of threads to be executed
ArrayList<String[]> nodes = new ArrayList<String[]>()
future = pool.submit(new PingNode(nodes));
}
}
};
timer.scheduleAtFixedRate(task, 0, interval);
while(true){
try{
ArrayList<String[]> tempOutputArray = future.get();
Iterator<String[]> it = tempOutputArray.iterator();
while(it.hasNext()) appendFile(it.next());
tempOutputArray.clear();
}catch(Exception nullException){
//Do nothing
}
}
}
Your problem is that you are modifying the future static field without synchronization in your timer-task thread(s) and reading it in the main thread. You need to either synchronize on it when you modify and read it or use another mechanism to share information between the threads.
I'd recommend switching from a static field to a LinkedBlockingQueue as a better way to send information from the PingNode call to the appendFile(...) method. This saves from needing to do the synchronization yourself and protects against the race conditions where multiple timer-tasks will start and overwrite the future before the consumer can get() from them. Maybe something like:
BlockingQueue<String[]> queue = new LinkedBlockingQueue<String[]>();
...
// inside of run, producer passes the queue into the PingNode
public void run() {
pool.submit(new PingNode(queue));
}
// consumer
while (true) {
String[] array = queue.take();
...
}
This doesn't take into effect how you are going to stop the threads when you are done. If the timer task is killed the entity could add to the queue a termination object to stop the main loop.
A Future object is not a bin, like an ArrayList, it merely points to a single computational result. Because you only have one static pointer to this Future, what I imagine is happening is this:
future = null
nullException
nullException
nullException
nullException
...
First thread finally sets future = Future<ArrayList<String>>
Call to future.get() blocks...
Meanwhile, all other threads get scheduled, and they reassign future
The last thread will obviously get the last say in what future points to
Data is gathered, written to file, loop continues
future now points to the Future from the last thread
Results from last thread get printed

Invoking different methods on threads

I have a main process main. It creates 10 threads (say) and then what i want to do is the following:
while(required){
Thread t= new Thread(new ClassImplementingRunnable());
t.start();
counter++;
}
Now i have the list of these threads, and for each thread i want to do a set of process, same for all, hence i put that implementation in the run method of ClassImplementingRunnable.
Now after the threads have done their execution, i wan to wait for all of them to stop, and then evoke them again, but this time i want to do them serially not in parallel.
for this I join each thread, to wait for them to finish execution but after that i am not sure how to evoke them again and run that piece of code serially.
Can i do something like
for(each thread){
t.reevoke(); //how can i do that.
t.doThis(); // Also where does `dothis()` go, given that my ClassImplementingRunnable is an inner class.
}
Also, i want to use the same thread, i.e. i want the to continue from where they left off, but in a serial manner.
I am not sure how to go about the last piece of pseudo code.
Kindly help.
Working with with java.
You can't restart a thread.
What you could do is use the java.util.concurrent package to wait for the threads to finish and rerun you runnables in the main thread to run them sequentially - by putting your runnables in a list, you can access them during the sequential run.
ExecutorService executor = Executors.newFixedThreadPool(10);
List<Runnable> runnables = new ArrayList<Runnable> ();
for (int i = 0; i < 10; i++) {
Runnable r = new ClassImplementingRunnable();
runnables.add(r);
executor.submit(r);
}
executor.shutdown();
//wait until all tasks are finished
executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
//re run the tasks sequentially
for (ClassImplementingRunnable r : runnables) {
//the method below can access some variable in
//your ClassImplementingRunnable object, that was
//set during the first parallel run
r.doSomethingElse();
}
If you want serial execution, just use
for (int i = 0; i < 10; i++)
new ClassImplementingRunnable().run();
all the tasks will run in the same thread, one after the other. This is the cleanest way to achieve what you want.
Update
After your comment it is clear that you in fact don't want to run the same tasks again, but to print the results that were calculated by them. This would be even simpler:
add the ClassImplementingRunnable instances into a list of tasks;
run each task in its own thread;
join all the threads;
write a for loop that prints the results from each ClassImplementingRunnable instance.
You already have 2 and 3.
I guess you want something like
ExecutorCompletionService
Example copied from Java doc.
Usage Examples. Suppose you have a set of solvers for a certain problem, each returning a value of some type Result, and would like to run them concurrently, processing the results of each of them that return a non-null value, in some method use(Result r). You could write this as:
void solve(Executor e,
Collection<Callable<Result>> solvers)
throws InterruptedException, ExecutionException {
CompletionService<Result> ecs
= new ExecutorCompletionService<Result>(e);
for (Callable<Result> s : solvers)
ecs.submit(s);
int n = solvers.size();
for (int i = 0; i < n; ++i) {
Result r = ecs.take().get();
if (r != null)
use(r);
}
}
Although there are some great answers here, I'm not sure your initial questions have been answered.
Now after the threads have done their execution, i wan to wait for all of them to stop, and then evoke them again, but this time i want to do them serially not in parallel.
You are confusing the running thread from it's object. It is a very common pattern (although usually made better with the ExecutiveService classes) to do something like the following:
List<ClassExtendingThread> threads = new ArrayList<ClassExtendingThread>();
// create your list of objects
for (int i = 0; i < 10; i++) {
ClassExtendingThread thread = new ClassExtendingThread(...);
thread.start();
threads.add(thread);
}
for (ClassExtendingThread thread : threads) {
// now wait for each of them to finish in turn
thread.join();
// call some method on them to get their results
thread.doThis();
}
Notice that I changed your class to extending Thread. It is usually better to implement Runnable like you did but if you are going to be joining and calling back to the objects, extending Thread makes the code easier.
So you create your object instances, start them as threads, and then join() with them which both waits for them to finish and synchronizes their memory. Once you join() with the thread, you can call any of the methods on your objects that you'd like. That doesn't "re-evoke" the thread at all. It is just accessing the fields inside of your objects. If you try to do this while the thread is running then you need to worry about synchronization.

Categories

Resources