Control Multithreading in Java

393 views Asked by At

I have one "Runnable" threads which is initiating few "Callable" threads and I want to display results when all above threads has finished their jobs.

What is the best way to do it?

My code is as follows

Connector.java (Starting Runnable Thread)

  public class Connector {
                      private static void anyFileConnector() {
                    // Starting searching Thread
                        ExecutorService executor = Executors.newFixedThreadPool(100);
                        executor.submit(traverse, executor);
//HERE I WANT MY ALL SEARCH RESULTS/OUTPUT : CURRENTLY IT IS STARTING OTHER THREADS AND NOT SHOWING ME ANY RESULTS BECAUSE NONE OF THEM WAS FINISHED.(IN CONSOLE, I WAS ABLE TO SEE RESULTS FROM ALL THE THREADS
        setSearchResult(traverse.getResult());

                    executor.shutdown();
            }
    }

Traverse.java (Runnable Thread) I am using ExecutorCompletionService to handle it...but it didn't create any difference. :(

public class Traverse implements Runnable {
    public void run() {

    ExecutorService executor = Executors.newFixedThreadPool(100);
    ExecutorCompletionService<List<ResultBean>> taskCompletionService =
            new ExecutorCompletionService<List<ResultBean>>(executor);
    try (DirectoryStream<Path> stream = Files
            .newDirectoryStream(dir)) {
                Search newSearch = new Search();
                taskCompletionService.submit(newSearch);
     }
    list.addAll(taskCompletionService.take().get());
    }
}

Search.java (Callable Thread)

public class Search implements Callable<List<ResultBean>> {
 public List<ResultBean> call() {
        synchronized (Search.class) {
// It will return results
            return this.search();
        }
    }

}
3

There are 3 answers

0
Alex Suo On

Easy - all the Callables will return Future objects which you can used to wait and get the result by calling Future.get() in a blocking wait way. So your problem is just a for loop waiting for each future on the callables blockingly.

After that, just aggregate the results to return to client.

0
Tushu On

The submit method of executor service can return a list of Future objects. What you can do for your case is call isDone() method of these Future objects in a while loop.

Whenever, any future task gets completed this method will return true. You can now call get() method on this to get the value returned by this task. In this way you could get hold of all the future task values without having to wait for any particular task to get complete (since your first future task could have the longest completion time)

7
Lokesh On

Go for CyclicBarrier and you will be able to achieve this. A cyclic barrier will perform a task as soon as all the threads are done with their work, this is where you can print the en result.

Check this lik for working of CyclicBarrier : http://javarevisited.blogspot.com/2012/07/cyclicbarrier-example-java-5-concurrency-tutorial.html