ScheduledThreadPoolExecutor e corePoolSize 0?

Mi piacerebbe avere un ScheduledThreadPoolExecutor che ferma 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.

L’ho ingenuamente creato come new ScheduledThreadPoolExecutor(0) ma, di conseguenza, nessun thread è mai stato creato, né viene eseguita alcuna operazione pianificata.

Qualcuno può dirmi se riesco a raggiungere il mio objective senza scrivere il mio wrapper su ScheduledThreadpoolExecutor ?

Grazie in anticipo!

In realtà puoi farlo, ma non è ovvio:

  • Crea un nuovo ScheduledThreadPoolExecutor
  • Nel costruttore imposta i thread principali sul numero massimo di thread che vuoi
  • imposta keepAliveTime dell’esecutore
  • e, infine, consentire il timeout dei thread principali

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

    Questo funziona solo con Java 6 però

Leggendo il file ThreadPoolExecutor javadocs 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.

Sospetto che nulla fornito in java.util.concurrent lo farà per te, solo perché se hai bisogno di un servizio di esecuzione pianificato, spesso hai compiti ricorrenti da eseguire. Se si dispone di un’attività ricorrente, in genere ha più senso mantenere lo stesso thread e utilizzarlo per la ricorrenza successiva dell’attività, piuttosto che abbattere il thread e doverne crearne uno nuovo alla ricorrenza successiva.

Naturalmente, un esecutore pianificato potrebbe essere utilizzato per inserire 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 all’arrivo di nuovi lavori. Quindi, posso vedere casi in cui la tua proposta avrebbe sicuramente un senso.

Per implementarlo, 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 a thread singolo (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 un massimo di un thread in esecuzione quando non c’è assolutamente lavoro da fare, e ti darebbe tutti i thread di cui hai bisogno (entro i limiti del tuo sistema, ovviamente) quando c’è molto lavoro da fare .

Questo problema è un bug noto in ScheduledThreadPoolExecutor ( ID bug 7091003 ) ed è stato corretto in Java 7u4. Pur osservando la patch , la correzione è che “almeno un thread viene avviato anche se corePoolSize è 0.”