Can a Runnable add a new thread to a ExecutorService?
Hello,
I have a question about the ExecutorService. Lets says I have the following scenarion:
import java.util.concurrent.*;
import java.util.Random;
publicclass UsePool{
publicstaticvoid main(String args[]){
Random random =new Random();
ExecutorService executor =
Executors.newFixedThreadPool(3);
// Sum up wait times to know when to shutdown
int waitTime = 500;
for (int i=0; i<10; i++){
String name ="NamePrinter " + i;
int time = random.nextInt(1000);
waitTime += time;
Runnable runner =new NamePrinter(name, time);
System.out.println("Adding: " + name +" / " + time);
executor.execute(runner);
}
try{
Thread.sleep(waitTime);
executor.shutdown();
executor.awaitTermination
(waitTime, TimeUnit.MILLISECONDS);
}catch (InterruptedException ignored){
}
System.exit(0);
}
}
publicclass NamePrinterimplements Runnable{
privatefinal String name;
privatefinalint delay;
public NamePrinter(String name,int delay){
this.name = name;
this.delay = delay;
}
publicvoid run(){
System.out.println("Starting: " + name);
try{
Thread.sleep(delay);
}catch (InterruptedException ignored){
}
System.out.println("Done with: " + name);
}
}
What I'd like to do, is modify this scenario so that the NamePrinter class can add other NamePrinter threads to the ExecutorService in UsePool - is it possible to do that? Any ideas how?
mmmm.... not sure about that, maybe I misunderstood your suggestion, but this is what I tried:
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.Random;
public class UsePool {
public static ExecutorService executor;
public static void main(String args[])
{
Random random = new Random();
executor = Executors.newFixedThreadPool(1);
// Sum up wait times to know when to shutdown
int waitTime = 500;
for (int i = 0; i < 10; i++)
{
String name = "NamePrinter " + i;
int time = random.nextInt(1000);
waitTime += time;
Runnable runner = new NamePrinter(executor, name, time);
System.out.println("Adding: " + name + " / " + time);
executor.execute(runner);
}
try
{
Thread.sleep(waitTime);
executor.shutdown();
executor.awaitTermination(waitTime, TimeUnit.MILLISECONDS);
} catch (InterruptedException ignored) {
}
System.exit(0);
}
}
class NamePrinter implements Runnable {
private final String name;
private final int delay;
private final ExecutorService oExec;
public NamePrinter(ExecutorService oExec, String name, int delay)
{
this.oExec = oExec;
this.name = name;
this.delay = delay;
}
public void run()
{
System.out.println("Starting: " + name);
try {
Thread.sleep(delay);
} catch (InterruptedException ignored) {
System.out.println( ignored );
}
System.out.println("Done with: " + name);
if ( name.equals( "NamePrinter 9" ) )
oExec.execute( new NamePrinter(oExec, "Test1", 3000) );
else if ( name.equals( "Test1" ) )
oExec.execute( new NamePrinter(oExec, "Test2", 3000) );
}
}
It crashed when I tries to add Test2 (which is a child of a child of the root node):
Starting: NamePrinter 9
Done with: NamePrinter 9
Starting: Test1
Done with: Test1
Exception in thread "pool-1-thread-1" java.util.concurrent.RejectedExecutionException
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1759)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:767)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:658)
at Sandbox.NamePrinter.run(NamePrinter.java:35)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
at java.lang.Thread.run(Thread.java:619)