Desidero creare un pool di thread memorizzato nella cache, ma funziona come uno fisso. Attualmente ho questo codice:Pool di ridimensionamenti non ridimensionato
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 "";
}
}
Se corro il codice ottengo uscita:
pool-1-thread-1 is ready
pool-1-thread-2 is ready
pool-1-thread-1 is ready
pool-1-thread-2 is ready
...
Significato solo 2 le discussioni stanno facendo tutto il lavoro e non nuovi thread di lavoro vengono aggiunti al pool. Non dovrebbe il threadpool generare più thread se le attività sono in attesa in coda (fino a 10 nel mio caso)?
Non voglio usare Executors.newCachedThreadPool()
perché non ha praticamente alcun limite superiore sui thread massimi e ha corePoolSize
0. Voglio avere sempre dei thread pronti per una migliore reattività.
----- ----- modificare 1
Grazie Aleksey per la risposta. L'impostazione della capacità di accodamento sta comportando il comportamento previsto, ma ora ho un nuovo problema.
La quantità di attività in background varia molto. La maggior parte delle volte 0 ma può andare fino a 50 attività simultanee per brevi periodi. Quale sarebbe un modo efficace per gestire questo? Tenere presente che la maggior parte delle attività in background è di breve durata (< 1s) ma anche alcune attività di lunga durata (> 1min).
Se ho impostato la mia threadpool in questo modo:
ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
sarò più probabile ottenere RejectedExecutionException con picchi di utilizzo. Tuttavia, se ho impostato ThreadPool in questo modo:
ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(200));
Poi sarà mai aggiunti nuovi thread di lavoro perché la coda non sarà max fuori.
La CPU ha almeno 4 core, quindi questo sarebbe uno spreco a mio parere. E la maggior parte delle volte non ci sono attività di background (80% del tempo di attività), quindi mantenere un pool di thread fisso sarebbe anche dispendioso secondo me.
Grazie per averlo chiarito. Ma ora sto ricevendo RejectedExecutionException (dimensione del pool = 10, thread attivi = 10, attività in coda = 10) poiché la coda viene riempita e vengono utilizzati anche tutti i thread attivi. –