Problema con gli executors

di il
3 risposte

Problema con gli executors

Ciao a tutti! avrei un problemino con gli Executors:
devo fare una serie da calcoli tutti uguali, per velocizzare il processo ho pensato quindi di utilizzare gli ExecutorSerivces.

volevo usare un FixedThreadPool per assicurarmi che vengano eseguiti n calcoli paralleli per volta ma questo tipo di esecutore, una volta l'esecuzione della classe classe Callable, tiene in memoria la classe e non libera la RAM; per ovviare a questo problema ho pensato di usare un CachedThreadPool che, una volta eseguito il calcolo elimina la classe.

Per fare in modo di fare N calcoli alla volta ho fatto un ciclo for che fa partire N calcoli, si ferma, aspetta la fine dell'esecuzione e va avanti.... io invece vorrei fare in modo che quando finisce un calcolo ne parta subito dopo un'altro....

come si può fare?

3 Risposte

  • Re: Problema con gli executors

    lory1990 ha scritto:


    per ovviare a questo problema ho pensato di usare un CachedThreadPool che, una volta eseguito il calcolo elimina la classe.
    "Eliminare la classe" ... in che senso? Nel senso di rimuovere la definizione a livello di class-loader? Sai cosa vuol dire?

    lory1990 ha scritto:


    in modo che quando finisce un calcolo ne parta subito dopo un'altro....
    Questo che hai appena descritto è uno scenario sequenziale ... non "concorrente". Quindi? Non ho capito ....
  • Re: Problema con gli executors

    Forse mi sono espresso male, volevo dire eliminare l'oggetto istanziato per fare il calcolo.

    Per quanto il tipo di calcolo vorrei appunto passare da uno scenario sequenziale ad uno concorrente... ma è impossibile eseguire 10.000 calcoli tutti insieme, questo è il senso
  • Re: Problema con gli executors

    lory1990 ha scritto:


    volevo dire eliminare l'oggetto istanziato per fare il calcolo.
    Premessa: i thread-pool utilizzano una "coda" per tenere accodati i lavori in attesa da sottomettere poi ai thread nel pool. La coda concettualmente può essere bounded o unbounded (con o senza limite). Se usi le factory in Executors ci sono dei default predefiniti, mentre se usi es. ThreadPoolExecutor hai possibilità di configurare questo e altri aspetti in modo più fine.

    Il succo comunque è questo: se la coda è unbounded (senza limite) e tu sottometti task molto velocemente, di più di quanto ci mettono ad essere eseguiti, la coda per forza continuerà a riempirsi. Se ne sottometti 10000, avrai che il thread-pool tiene referenziati in modo "strong" 10000 oggetti Runnable/Callable. E se ciascuno di questi è molto "pesante" (referenzia lunghe stringhe, array, ecc...) allora ovviamente può essere un bel problema. Se è così, devi valutare tu la questione e la soluzione.

    Una volta che il thread-pool toglie il Runnable/Callable dalla coda e l'ha eseguito, non lo tiene più referenziato! Se tu li tieni tutti referenziati per altri tuoi motivi, idem può essere un problema.

    lory1990 ha scritto:


    ma è impossibile eseguire 10.000 calcoli tutti insieme, questo è il senso
    Se i task sono estremamente cpu-bound (ovvero usano principalmente la cpu e poco/nulla del I/O), allora il numero "ottimale" di thread sai quanto è? E' esattamente uguale al numero di core presenti nella macchina. Se la macchina ha 8 core, quello è il numero ottimale di thread che usano la cpu in modo intensivo. Se aumenti il numero (es. il doppio) è ancora possibile/accettabile ma ovviamente aumentano i context switch e quindi man mano degradano le performance generali.

    Comunque avere 10000 thread non ha senso. Tieni presente che ogni thread consuma svariate risorse native e per ciascun thread viene istanziato uno spazio di memoria per lo stack. La FAQ ufficiale Oracle su Java HotSpot VM dice:

    On Windows, the default thread stack size is read from the binary (java.exe). As of Java SE 6, this value is 320k in the 32-bit VM and 1024k in the 64-bit VM.

    Quindi su una VM 64 bit per default ogni thread usa uno stack da 1MByte. Con 10000 thread avresti bisogno di una macchina con più di 10GB di ram ... poco sensato.
    Lo stack size è configurabile, ma anche se lo metti di 64k, vorrebbe dire ~640MB che è già più accettabile ma comunque da verificare se è appropriato o meno.

    Senza contare che con 10000 thread intensivi sulla cpu, avresti un numero elevatissimo di context switch .....

    Quindi cosa è che vuoi esattamente?
Devi accedere o registrarti per scrivere nel forum
3 risposte