2010-02-25 6 views
15

Mi piacerebbe avere uno ScheduledThreadPoolExecutor che interrompa anche l'ultimo thread se non c'è lavoro da fare e crea (e mantiene i thread attivi per qualche tempo) se ci sono nuove attività. Ma una volta che non c'è più lavoro da fare, dovrebbe di nuovo scartare tutti i thread.ScheduledThreadPoolExecutor e corePoolSize 0?

L'ho creato in modo ingenuo come new ScheduledThreadPoolExecutor(0) ma, di conseguenza, non viene mai creato alcun thread né viene eseguita alcuna operazione pianificata.

Qualcuno può dirmi se riesco a raggiungere il mio obiettivo senza scrivere il mio involucro attorno allo ScheduledThreadpoolExecutor?

Grazie in anticipo!

+1

Sembra che tu voglia qualcosa che crea e abbatte i thread come un 'ExecutorService' da' Executors.newCachedThreadPool() ', a parte il fatto che ti piacerebbe implementare l'interfaccia' ScheduledExecutorService' invece di solo 'ExecutorService' interfaccia. È un riassunto accurato? –

+0

In realtà, si, è un riassunto abbastanza accurato. –

risposta

14

In realtà si può fare, ma la sua non ovvia:

  • Creare un nuovo ScheduledThreadPoolExecutor
  • Nel costruttore impostare i thread di base per il numero massimo di thread che si desidera
  • impostare il KeepAliveTime dell'esecutore
  • e infine, consentire i fili di base per timeout

    m_Executor = new ScheduledThreadPoolExecutor (16,null); 
    m_Executor.setKeepAliveTime (5, TimeUnit.SECONDS); 
    m_Executor.allowCoreThreadTimeOut (true); 
    

    Questo funziona solo con Java 6 se

+0

Mille grazie, sembra proprio esattamente quello di cui ho bisogno. –

7

Ho il sospetto che nulla fornito in java.util.concurrent lo farà per voi, solo perché se avete bisogno di un servizio di esecuzione pianificata, spesso avete attività ricorrenti da eseguire. Se si dispone di un'attività ricorrente, il valore di solito ha più senso semplicemente mantenere lo stesso thread e utilizzarlo per la ricorrenza successiva dell'attività, piuttosto che abbattere il thread e dover crearne uno nuovo alla successiva ricorrenza .

Naturalmente, un esecutore pianificato può essere utilizzato per l'inserimento di ritardi tra attività non ricorrenti, oppure potrebbe essere utilizzato nei casi in cui le risorse sono così scarse e la ricorrenza è così rara che ha senso abbattere tutti i thread fino a nuovo lavoro arriva. Quindi, posso vedere casi in cui la tua proposta avrebbe sicuramente un senso.

Per implementare questo, vorrei prendere in considerazione il tentativo di racchiudere un pool di thread memorizzato nella cache da Executors.newCachedThreadPool insieme a un servizio di esecuzione di un programma con un solo thread (ad esempio new ScheduledThreadPoolExecutor(1)). Le attività possono essere pianificate tramite il servizio di esecuzione pianificata, ma le attività pianificate vengono archiviate in modo tale che anziché eseguirle con un programma di esecuzione pianificata a thread singolo, l'executor a thread singolo le passerà al pool di thread memorizzato nella cache per l'effettivo esecuzione.

Quel compromesso ti darebbe il massimo di un thread in esecuzione quando non c'è assolutamente lavoro da fare e ti darebbe tutti i thread necessari (nei limiti del tuo sistema, ovviamente) quando ci sono molti di lavoro da fare.

+0

Grazie per la risposta abbozzata. In realtà, sto usando ScheduledThreadPool per operazioni ritardate, non per azioni ripetute. E la maggior parte delle azioni sono azioni una tantum e odio creare un Thread ogni volta e odio anche condividere in modo esplicito un ScheduledExecutorService manualmente tra le varie classi che devono farlo. –

8

Leggendo i javadocs ThreadPoolExecutor potrebbe suggerire che la soluzione di Alex V è a posto. Tuttavia, facendo ciò si otterranno inutilmente la creazione e la distruzione di thread, niente come un pool di thread incassato. ScheduledThreadPool non è progettato per funzionare con un numero variabile di thread. Dopo aver esaminato la fonte, sono sicuro che finirai generando un nuovo thread quasi ogni volta che invii un'attività. La soluzione di Joe dovrebbe funzionare anche se stai inviando SOLO compiti in ritardo.

PS.Monitorerei i tuoi thread per assicurarti che non sprechi risorse nella tua attuale implementazione.

5

Questo problema è un bug noto in ScheduledThreadPoolExecutor (Bug ID 7091003) ed è stato risolto in Java 7u4. Sebbene sia looking at the patch, la correzione è che "almeno un thread viene avviato anche se corePoolSize è 0."