Java Language ThreadPoolExecutor

Esempio

Un Executor comune utilizzato è il ThreadPoolExecutor , che si occupa della gestione dei thread. È possibile configurare la quantità minima di thread che l'executor deve sempre mantenere quando non c'è molto da fare (si chiama dimensione del core) e una dimensione massima del thread a cui il Pool può crescere, se c'è più lavoro da fare. Una volta che il carico di lavoro diminuisce, il Pool riduce lentamente il numero di thread fino a quando non raggiunge la dimensione minima.

ThreadPoolExecutor pool = new ThreadPoolExecutor(
    1,                                     // keep at least one thread ready, 
                                           // even if no Runnables are executed
    5,                                     // at most five Runnables/Threads
                                           // executed in parallel
    1, TimeUnit.MINUTES,                   // idle Threads terminated after one
                                           // minute, when min Pool size exceeded
    new ArrayBlockingQueue<Runnable>(10)); // outstanding Runnables are kept here

pool.execute(new Runnable() {
    @Override public void run() {
        //code to run
    }
});

Nota Se si configura ThreadPoolExecutor con una coda illimitata , il conteggio dei thread non supererà corePoolSize poiché i nuovi thread vengono creati solo se la coda è piena:

ThreadPoolExecutor con tutti i parametri:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, 
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)

da JavaDoc

Se ci sono più di corePoolSize ma meno di maximumPoolSize thread in esecuzione, verrà creato un nuovo thread solo se la coda è piena.

vantaggi:

  1. La dimensione di BlockingQueue può essere controllata e gli scenari di esaurimento della memoria possono essere evitati. Le prestazioni dell'applicazione non saranno ridotte con le dimensioni limitate della coda limitata.

  2. È possibile utilizzare esistenti o creare nuove politiche del gestore di rifiuto.

    1. Nel file ThreadPoolExecutor.AbortPolicy predefinito, il gestore rilascia una RejectedExecutionException di runtime in caso di rifiuto.

    2. In ThreadPoolExecutor.CallerRunsPolicy , il thread che richiama execute esegue l'attività. Ciò fornisce un semplice meccanismo di controllo di feedback che rallenta la velocità con cui vengono inviate nuove attività.

    3. In ThreadPoolExecutor.DiscardPolicy , un'attività che non può essere eseguita viene semplicemente eliminata.

    4. In ThreadPoolExecutor.DiscardOldestPolicy , se l'executor non viene arrestato, l'attività in testa alla coda di lavoro viene interrotta e quindi l'esecuzione viene ritentata (che può fallire nuovamente, provocando la ripetizione).

  3. ThreadFactory possibile configurare Custom ThreadFactory , che è utile:

    1. Per impostare un nome di thread più descrittivo
    2. Per impostare lo stato del daemon del thread
    3. Per impostare la priorità del thread

Ecco un esempio di come utilizzare ThreadPoolExecutor