0

I have initialized a exectuor service with N threads. After the N threads finishes i want to wait for a while and then reuse the executor with new instance of N threads. How do i do this?

Here is the sample code i am using that is failing:

 int NumberOfThreads=Integer.parseInt(PropertyHandler.getProperty("numberOfThreads")); ExecutorService executor = Executors.newFixedThreadPool(NumberOfThreads); log.info("Executor class has been initialized"); while (true) { jobStack = MrMestri.buildJobs(); log.info("Creating a job stack of the search urls"); if (jobStack.isEmpty()) { Thread.sleep(10000); } else { int jobToken = 0; while (jobStack.size() > 0) { jobToken++; MrRunnable worker = new MrRunnable(jobStack.pop()); executor.execute(worker); if (jobToken% Integer.parseInt(PropertyHandler.getProperty("totalTrends")) == 0) { log.info("All jobs for the clock cycle complete , waiting for next clock cycle to start. Number of jobs completed " + jobToken); executor.shutdown(); Thread.sleep(milliseconds); } 

Now that i am using executor shutdown , there is no executor to execute my threads. And my threads implement runnable.

Any quick response would be of great help. Thank you.

2
  • Maybe executor.awaitTermination ? Commented Mar 30, 2014 at 18:57
  • await termination is used when u use executor.shutdown(). Or atleast what it seems like or when it times out. I dont know what time i can set there as some of my response might take time. So i dont think i want to take that route. Commented Mar 30, 2014 at 19:08

2 Answers 2

3

Just not shut down your executor - reuse it instead. Generate a collection of Callable tasks instead of Runnable and use:

executor.invokeAll 

It will execute all tasks and return as soon as all of them are done. If MrRunnable is not your class or for whatever reason it have to implements Runnable you can simply convert it to Callable like:

new Callable<Void>() { @Override public Void call() throws Exception { worker.run(); return null; } }; 
Sign up to request clarification or add additional context in comments.

Comments

1

The problem is with below line that is placed inside while loop.

jobStack = MrMestri.buildJobs(); 

In this case below condition will always return false because jobStack is never empty if you want to process next N tasks

jobStack.isEmpty() 

Move this condition in inner while loop and break inner loop if condition meets to process next N tasks.


Sample code:

import java.util.Stack; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Executor { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { int NumberOfThreads = Integer.parseInt("10"); ExecutorService executor = Executors.newFixedThreadPool(NumberOfThreads); while (true) { Stack<Job> jobStack = MrMestri.buildJobs(); int jobToken = 0; while (true) { if (jobStack.size() > 0) { jobToken++; MrRunnable worker = new MrRunnable(jobStack.pop()); executor.execute(worker); if (jobToken % Integer.parseInt("4") == 0) { // executor.shutdown(); System.out.println("short waiting..."); Thread.sleep(2000); } } else { System.out.println("long waiting..."); Thread.sleep(10000); break; } } } } } class MrMestri { public static Stack<Job> buildJobs() { Stack<Job> stack = new Stack<Job>(); stack.push(new Job("A")); stack.push(new Job("B")); stack.push(new Job("C")); stack.push(new Job("D")); stack.push(new Job("E")); stack.push(new Job("F")); return stack; } } class MrRunnable implements Runnable { private Job job; public MrRunnable(Job j) { job = j; } @Override public void run() { System.out.println(job.getName()); } } class Job { private String name; public Job(String n) { name = n; } public String getName() { return name; } public void setName(String name) { this.name = name; } } 

5 Comments

Thank you , i think this usage of loops is awesome. I never thought about it this way . Had to take a step back to look at my code! so awesome!
This solves a problem in the original code but is not the proper way to wait for threads to complete. There's almost always a better approach than calling Thread.sleep, whatever the problem. See the invokeAll answer below.
But i do need it to sleep right? invokeall would let me know if all threads are finished but after that i still need to use thread sleep. So is the above given approach still not right?
Put a check for outer while loop also. If jobStack is empty then come out of outer while loop as simple as it is.
exactly what i did now :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.