2016-01-17 7 views
5

Esecutori # newFixedThreadPool:Perché utilizzare una coda diversa durante la creazione di FixedThreadPool e CachedThreadPool?

public static ExecutorService newFixedThreadPool(int nThreads) { 
    return new ThreadPoolExecutor(nThreads, nThreads, 
            0L, TimeUnit.MILLISECONDS, 
            new LinkedBlockingQueue<Runnable>()); 
} 

Esecutori # newCachedThreadPool:

public static ExecutorService newCachedThreadPool() { 
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 
            60L, TimeUnit.SECONDS, 
            new SynchronousQueue<Runnable>()); 
} 

Perché i due ThreadPool usano coda diversa? Ho cercato java doc su LinkedBlockingQueue e SynchronousQueue, ma ancora non so perché vengono utilizzati qui, sono le prestazioni in considerazione o altri?

+0

È un duplicato? Non fa la stessa domanda. La risposta può avere qualcosa in comune, ma è una domanda diversa. –

+0

Motivo dalla relativa domanda SE: SynchronousQueue è un tipo molto speciale di coda: implementa un approccio di rendez-vous (il produttore attende fino a quando il consumatore è pronto, il consumatore attende che il produttore sia pronto) dietro l'interfaccia di Queue. –

risposta

0

La risposta è nella documentazione del ThreadPoolExecutor classe:

  • Queuing
    • Qualsiasi {@link BlockingQueue} può essere utilizzato per trasferire e tenere
    • compiti presentati . L'uso di questa coda interagisce con il dimensionamento del pool: * *
        * *
      • Se sono in esecuzione meno di thread CorePoolSize, l'Executor * preferisce sempre aggiungere un nuovo thread * anziché l'accodamento .
      • * *
      • Se corePoolSize o più thread sono in esecuzione, l'Executor * preferisce sempre mettere in coda una richiesta piuttosto che aggiungere un nuovo thread * .
      • * *
      • Se una richiesta non può essere accodata, viene creato un nuovo thread a meno che * questo non superi maximumPoolSize, nel caso , l'attività sarà * respinta.
      • * *
      * * Lì sono tre strategie generali per l'accodamento: * * *
    • Handoff diretti. Una buona scelta predefinita per una coda * di lavoro è {@link SynchronousQueue} che trasferisce le attività ai thread * senza altrimenti trattenendoli. In questo caso, un tentativo di accodamento di un'attività * non riuscirà a se nessun thread è immediatamente disponibile per eseguirlo, quindi verrà creato * un nuovo thread . Questa politica evita i blocchi quando * gestisce gli insiemi di richieste che potrebbero avere dipendenze interne. * Gli handoff diretti richiedono generalmente maximumPoolSizes illimitati per * evitare il rifiuto delle nuove attività inviate . Ciò a sua volta ammette la * possibilità di crescita dei thread illimitata di quando i comandi continuano a * arrivare in media più velocemente di quanto possano essere elaborati.
    • * *
    • Code illimitate .L'utilizzo di una coda illimitata (per * esempio a {@link LinkedBlockingQueue} senza una capacità * predefinita) causerà l'attesa di nuove attività nella coda quando tutti i thread * corePoolSize sono occupati. Pertanto, non verranno mai creati più thread corePoolSize *. (E il valore di maximumPoolSize * pertanto non ha alcun effetto .) Questo può essere appropriato quando * ogni attività è completamente indipendente dalle altre, quindi le attività non possono * influire l'una sull'altra esecuzione; ad esempio, in un server di pagine Web.* Anche se questo stile di accodamento può essere utile per uniformare * transitori di transitori delle richieste , ammette la possibilità di * crescita della coda di lavoro illimitata quando i comandi continuano ad arrivare su * media più velocemente di quanto possano essere elaborati .
    • * *
    • Code bloccate. Una coda limitata (ad esempio, * {@link ArrayBlockingQueue}) aiuta a prevenire l'esaurimento delle risorse quando * viene utilizzato con un massimo di MaximumPoolSizes, ma può essere più difficile * regolare e controllare * . Le dimensioni della coda e le dimensioni massime del pool possono essere scambiate * l'una per l'altra: l'utilizzo di code grandi e piccoli pool riduce al minimo * l'utilizzo della CPU, le risorse del sistema operativo e il cambio di contesto overhead, ma può * portare a un throughput artificialmente basso. Se le attività bloccano frequentemente (per * esempio se sono vincolate a I/O), un sistema può essere in grado di pianificare * l'ora per più thread di quanto altrimenti consentito. L'uso di code piccole * richiede generalmente dimensioni di pool più grandi, che mantiene le CPU più occupate ma * potrebbe verificarsi un sovraccarico di pianificazione inaccettabile , che inoltre * riduce il throughput.

In pratica il primo tipo di coda di invio subito ai thread disponibili una nuova Runnable, il secondo tipo lo tiene se tutti i thread sono occupati.

+0

Entrambi APIS restituiscono le code illimitate. –

+0

@ravindra Modificata la mia risposta –

Problemi correlati