HalJordan ha scritto:
k potrebbe essere più grande dell'array Runnable.
Se k è maggiore del numero di Runnable succede una cosa molto semplice: non ci sarà mai una situazione di "blocco" (thread che va in sospensione) nel put() della coda. E quindi sarebbe né più né meno che fare un banale for sui runnable e avviarli uno per uno, senza alcuna coda di mezzo.
HalJordan ha scritto:
non ho capito granchè da queste code bloccanti
ArrayBlockingQueue è una coda:
a) basata su un array interno che rimane sempre di quella dimensione prefissata. Insomma è una "bounded" queue, cioè la dimensione è
limitata
b) "blocking", nel senso di bloccante, cioè una invocazione di take() si blocca (thread va in sospensione) se la coda è
vuota mentre put() si blocca se la coda è
piena (proprio perché "limitata"). Poi ci sono altri metodi bloccanti ma con possibile timeout.
HalJordan ha scritto:
Nella prima iterazione di ciclo, T1 viene inserito in q, viene fatto eseguire, esegue il suo run e con la sua fine rimuove T1 da q. In pratica q non sarà mai piena o non avrà mai k Thread. Sbaglio qualcosa?
Innanzitutto il corpo del ciclo è praticamente velocissimo. Crea un oggetto (tempo piccolissimo), fa un put, velocissimo (attenzione:
a meno che si blocchi) e fa uno start del Thread, velocissimo (mette solo il Thread in stato "runnable", non fa altro).
Quindi è ragionevole pensare che se k è minore del numero di Runnable si raggiunga praticamente immediatamente la condizione di coda "piena". Quindi al prossimo ciclo il put() si bloccherebbe. E da quel momento si sbloccherebbe solo man mano che un thread sta terminando e si "rimuove" da solo dalla coda.
Poi ovviamente dipende da quanto tempo occupano i Runnable. Prova a fare es. 30 Runnable che impiegano ciascuno anche 4, 5 o più secondi e metti k=5. Metti un System.out.println dopo il put per stampare qualcosa. Vedrai che all'inizio avrai
k put immediati e poi dopo un po' altri appena ciascun thread in esecuzione si toglie dalla coda.