2010-07-28 16 views
27

Posso immaginare che alcune attività pianificate richiedano molto tempo e ScheduledThreadPoolExecutor creerebbe thread aggiuntivi per le altre attività che devono essere eseguite, fino a quando non viene raggiunto un numero massimo di thread.Perché ScheduledThreadPoolExecutor accetta solo un numero fisso di thread?

Ma sembra che possa specificare solo un numero fisso di thread per il pool, perché è così?

risposta

11

Come il perché, non lo so neanche io. Ma posso immaginare.

La quantità di risorse di un computer è limitata. Non tutte le risorse possono essere gestite contemporaneamente.

Se più processi caricano contemporaneamente i file, verranno caricati più lentamente rispetto a quando sono stati caricati in sequenza (almeno su un disco rigido).

Un processore ha anche un supporto limitato per la gestione di più thread contemporaneamente. A un certo punto il sistema operativo o la JVM impiegheranno più tempo a cambiare i thread, mentre i thread spendono l'esecuzione del loro codice.

Questa è una buona ragione per cui lo ScheduledThreadPoolExecutor deve essere progettato così com'è. È possibile inserire qualsiasi quantità di lavori in coda, ma non vengono mai eseguiti più lavori contemporaneamente di quelli che possono essere eseguiti in modo efficiente. Spetta a te bilanciare questo, ovviamente.

Se le attività sono legate all'IO, impostarei la dimensione del pool piccola e, se sono collegate alla CPU, un po 'più grande (32 o giù di lì). È inoltre possibile creare più ScheduledThreadPoolExecutor s, uno per le attività associate all'IO e uno per le attività associate alla CPU.

6

Durante lo scavo di SchecduledThreadPoolExecutor ho trovato questo link, Questo collegamento spiega SchecduledThreadPoolExecutor risolve molti problemi della classe Timer. E anche la ragione per introdurre SchecduledThreadPoolExecutor era di sostituire Timer (a causa di vari problemi con Timer). Penso che la ragione per il numero fisso di thread passati a SchecduledThreadPoolExecutor sia in uno dei problemi risolti da questa classe. Ad esempio

La classe Timer avvia solo una discussione . Mentre è più efficiente rispetto alla creazione di un thread per attività, è non una soluzione ottimale. La soluzione ottimale può essere quella di utilizzare un numero di thread tra un thread per tutte le attività e un thread per attività. Nell'effetto , la soluzione migliore è posizionare le attività in un pool di thread. Il numero di thread nel pool deve essere assegnato durante la costruzione a per consentire al programma di determinare il numero ottimale di thread nel pool.

Quindi, a mio parere, questo è il caso di utilizzo di SchecduledThreadPoolExecutor. Nel tuo caso, dovresti essere in grado di decidere il valore ottimale in base alle attività che pianifichi di pianificare e al tempo necessario per completare queste attività. Se ho 4 attività di lunga durata programmate per la stessa ora, preferirei che la dimensione del mio pool fosse maggiore di 4 se ci sono altri compiti da eseguire nello stesso tempo. Preferirei anche separare le attività di lunga durata in diversi esecutori come indicato nelle risposte precedenti.

Spero che questo aiuti :)

3

Secondo Java Concurrency In Practice vi sono le seguenti svantaggi della creazione filo illimitata:

ai cicli di vita Discussione in testa

creazione dei thread e teardown non sono liberi. La creazione del thread richiede tempo e richiede alcune attività di elaborazione da parte della JVM e del sistema operativo.

consumo di risorse

le discussioni attive consumano risorse di sistema, in particolare la memoria. Quando ci sono più thread eseguibili rispetto ai processori disponibili, i thread rimangono inattivi. Avere molti thread inattivi può legare molta memoria, mettere pressione sul garbage collector e avere molti thread in competizione per le CPU può imporre anche altri costi di performance. Se hai abbastanza thread per mantenere occupate tutte le CPU, la creazione di più thread non aiuterà e potrebbe anche danneggiare.

Stabilità

C'è un limite al numero di thread può essere creato. Il limite varia a seconda della piattaforma ed è influenzato da fattori quali i parametri di chiamata JVM, la dimensione dello stack richiesta nel costruttore Thread e i limiti sui thread posizionati dal sistema operativo sottostante. Quando raggiungi il limite di htis, il risultato più probabile è un OutOfMemoryError. Cercare di recuperare da un tale errore è molto rischioso; è molto più semplice strutturare il programma per evitare di raggiungere questo limite.


Fino ad un certo punto, più thread possono migliorare la velocità, ma al di là di quel punto la creazione di più thread solo rallenta la vostra applicazione, e la creazione di un thread di troppo può causare l'intera applicazione in crash orribilmente. Il modo di stare fuori dal pericolo è mettere un po 'legato al numero di thread creati dall'applicazione e testare accuratamente l'applicazione per garantire che, anche quando viene raggiunto questo limite, non esaurisca le risorse.

La creazione di thread senza limiti potrebbe sembrare soddisfacente durante la prototipazione e lo sviluppo, con problemi che si verificano solo quando l'applicazione viene distribuita e sotto carico pesante.

Problemi correlati