Chcę utworzyć pulę wątków buforowanych, ale działa ona jako stała. Obecnie mam ten kod:Pula nici nie zmienia rozmiaru
public class BackgroundProcesses {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//ExecutorService threadPool2 = Executors.newCachedThreadPool();
ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
for (int i = 0; i < 800; i++) {
Callable<String> task = new Task();
threadPool.submit(task);
}
}
}
class Task implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " is ready");
return "";
}
}
Jeśli uruchomić kod otrzymuję wyjścia:
pool-1-thread-1 is ready
pool-1-thread-2 is ready
pool-1-thread-1 is ready
pool-1-thread-2 is ready
...
znaczenie tylko 2 wątki wykonują całą pracę i brak nowych wątków roboczych są dodawane do puli. Czy wątek nie powinien odradzać więcej wątków, jeśli zadania czekają w kolejce (do 10 w moim przypadku)?
Nie chcę używać Executors.newCachedThreadPool()
, ponieważ nie ma praktycznie górnego limitu maksymalnych wątków i ma on corePoolSize
0. Chcę mieć zawsze gotowe wątki dla lepszej reakcji.
----- edit 1 -----
Dziękuję Aleksey za odpowiedź. Ustawienie zdolności do kolejkowania powoduje, że zachowuje się zgodnie z oczekiwaniami, ale teraz mam nowy problem.
Ilość zadań wykonywanych w tle jest bardzo różna. W większości przypadków 0, ale można przejść do 50 równoczesnych zadań przez krótki czas. Jaki byłby skuteczny sposób radzenia sobie z tym? Należy pamiętać, że większość zadań wykonywanych w tle byłaby krótkotrwała (< 1s), ale także kilka długotrwałych zadań (> 1min).
Jeśli mogę ustawić puli wątków się tak:
ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
I najprawdopodobniej dostać RejectedExecutionException z wykorzystaniem piku. Jednak jeśli ustawić puli wątków się tak:
ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(200));
Następnie żadnych nowych wątków roboczych nigdy nie będzie dodana, ponieważ kolejka nie będzie max out.
Procesor ma co najmniej 4 rdzenie, więc moim zdaniem byłoby to marnotrawstwem. Przez większość czasu nie ma żadnych zadań wykonywanych w tle (80% więcej czasu), więc utrzymywanie stałej puli wątków byłoby w moim mniemaniu marnotrawstwem.
Dzięki za wyczyszczenie tego. Ale teraz otrzymuję wyjątek RejectedExecutionException (rozmiar puli = 10, aktywne wątki = 10, zadania w kolejce = 10), ponieważ kolejka zostaje wypełniona i wszystkie aktywne wątki są również używane. –