Search code examples
javamultithreadingthreadpool

How to restart terminated threads using ScheduledThreadpoolExecutor in Java?


I want to have a thread pool that is maintained to a constant number of threads. I want all the threads that are dying due to an exception or terminating gracefully, spawn up their exact replica to maintain the number of threads.

I've tried the following code to expect that it'll continuously keep printing 1-2-3-4-1-2-3-4.... in a loop however it stops after the first execution.

import org.junit.Test;
import java.util.Optional;
import java.util.concurrent.*;

public class Testing {
    @Test
    public void tet() {
        ScheduledExecutorService poolExecutor =
                new CustomExecutor(4);
        for (int i = 1; i <= 4; i++) {
            poolExecutor.execute(new Task(i));
        }
    }

}

class Task implements Runnable {

    int x;

    Task(int x) {
        this.x = x;
    }

    @Override
    public void run() {
        System.out.println(x);
        if (true) {
            System.out.println("throwing exception " + x);
            throw new RuntimeException();
        }
    }
}

class CustomExecutor extends ScheduledThreadPoolExecutor {

    public CustomExecutor(int corePoolSize) {
        super(corePoolSize);
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        this.execute(r);
    }
}

I changed the code to the following as suggested in the answer ::

    public class Testing {
    @Test
    public void tet() {
        ScheduledExecutorService poolExecutor = new ScheduledThreadPoolExecutor(4);
        for (int i = 1; i <= 4; i++) {
            poolExecutor.scheduleAtFixedRate(new Task(i), 0, 1000, TimeUnit.MILLISECONDS);
        }
    }
}
class Task extends Thread {

    int x;

    Task(int x) {
        this.x = x;
    }

    @Override
    public void run() {
        System.out.println(x);
    }
}

The output is not repeating. Am I doing something wrong here?


Solution

  • You don't need restart the dead thread mannully, when new task is submitted, the executor will check if it is necessary to create new thread.

    In this case, if you expect the task keep running after the exception, you can catch and handle it.

    Also, if you just execute the task, it will only be executed once. You should schedule them if you expect continous execution as well as wait for termination:

    @Test
    public void tet() {
        ScheduledExecutorService poolExecutor =
                new CustomExecutor(4);
        for (int i = 1; i <= 4; i++) {
            poolExecutor.scheduleAtFixedRate(new Task(i), 0, 1000, TimeUnit.MILLISECONDS);
        }
        try {
            poolExecutor.awaitTermination(10000, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
        }
    }