Как перезапустить завершенные потоки, используя ScheduledThreadpoolExecutor в Java? - PullRequest
0 голосов
/ 01 мая 2018

Я хочу иметь пул потоков с постоянным числом потоков. Я хочу, чтобы все потоки, которые умирают из-за исключения или изящно завершаются, порождают их точную копию, чтобы поддерживать количество потоков.

Я попробовал следующий код, чтобы ожидать, что он будет непрерывно печатать 1-2-3-4-1-2-3-4 .... в цикле, однако он останавливается после первого выполнения.

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);
    }
}

Я изменил код на следующий, как предложено в ответе:

    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);
    }
}

Выход не повторяется. Я что-то здесь не так делаю?

1 Ответ

0 голосов
/ 01 мая 2018

Вам не нужно перезапускать мертвый поток вручную, при отправке нового задания исполнитель проверит необходимость создания нового потока.

В этом случае, если вы ожидаете, что задача продолжит выполняться после исключения, вы можете перехватить его и обработать.

Кроме того, если вы просто execute, задача будет выполнена только один раз. Вы должны schedule их, если вы ожидаете непрерывного выполнения, а также wait для завершения:

@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) {
    }
}
...