Alan Zucconi

Priority Executor 23 October 2010

Chi ha esperienza di programmazione C o C++ si sarà spesso trovato, se non a dover reinventare la ruota, quantomeno a programmare uno spinterogeno.
La politica di Java su questo è stata chiara fin dall’inizio: una libreria per ogni cosa.
Java non è più un linguaggio. Java È le sue librerie.

Per questo mi ha stupito la totale assenza di un componente che, a mio avviso, sarebbe dovuto essere di serie.
Il package “concurrent“, per quanto non brilli per eleganza e facilità di utilizzo, contiene una miriade di classi dall’utilizzo non ben precisato. Per questo non è stato facilissimo realizzare che quello di cui avevo bisogno non era nascosto tra le classi, ma non c’era proprio!

Seguendo la nomenclatura Java, il componente in questione si chiama “PriorityExecutor“. Alla parola “pool di thread” c’è sempre qualcuno che ha un sobbalzo, e proprio per questo ho deciso di pubblicare un piccolo pacchetto già pronto all’utilizzo.

Immaginatevi di avere un pool di thread. Ed ora immaginatevi che i vostri thread abbiano una proprità. Non mi riferisco alla “Priority” nativa del package “concurrent“, ma al fatto che alcuni debbano essere eseguiti prima degli altri, e per più tempo. Ma ovviamente con l’assunzione che tutti possano passare in esecuzione, evitando spiacevoli deadlock o fenomeni di starvation.

Ecco, questa classe non esiste. O almeno, non esisteva. “PriorityExecutor” realizza proprio quanto descritto, in maniera semplice anche se non sempre elegantissima.

Tutti i thread che vogliono schedulare con questo meccanismo devono estendere la classe “FairyFIFOPriorityRunnable“. Il nome riassume perfettamente le caratteristiche che sono garantite:

  • Fairy: tutti i thread passano in esecuzione, evitando deadlock e starvation,
  • FIFO: a parità di priorità, la precedenza è data a chi è arrivato per primo,
  • Priority: ai thread con priorità maggiore è garantito un accesso più frequente all’esecuzione.

Vediamo come usarla:

class TestThread extends FairyFIFOPriorityRunnable {
	/* Costruttore */
	public TestThread (final int currentPriority) {
		super(currentPriority);
	}

	/* Il corpo del metodo */
	@Override
	public void run () {
		...
	}
}

Sarà sufficiente creare un “PriorityExecutor” e riempirla con un’istanza di questo thread:

	/* Due thread possono essere in esecuzione contemporanea */
	final PriorityExecutor pool = new PriorityExecutor(2);

	pool.execute( new TestThread(10)	);
	pool.execute( new TestThread(5)	);
	pool.execute( new TestThread(1)	);

Il funzionamento è facile. Ad ogni thread è associata una doppia priorità: quella “nominale”, scelta dall’utente, e quella “attuale” che viene incrementata o decrementata automaticamente per garantire le fairyness. Quando un thread è in esecuzione, ci resta fino alla fine del suo “run“. Una volta terminato, la sua priorità attuale viene decrementata. Una volta che la priorità è scesa a zero, viene rimessa al massimo.
Quindi, se un thread ha priorità doppia rispetto ad un altro, verrà mediamente schedulato il doppio delle volte.
È compito dell’utente inserire nuovamente il thread nella lista se vuole che questo concorra di nuovo all’esecuzione. In tal caso comunque, tutte le strutture dati sono già preparate in modo adeguato per gestire il reinserimento ed i cambiamenti di priorità.
Possiamo ottenere questo effetto con facilità sovrascrivendo il metodo “afterExecute” della classe “FairyFIFOPriorityRunnable“:

	/* Lo rimette in coda */
	@Override
	public void afterExecute (final Throwable t) {
		/* Senza questa riga, il meccanismo di priorità non funzionerà più! */
		super.afterExecute(t);

		/* Si rimette in coda */
		pool.execute(this);
	}

Il pacchetto completo con binari, sorgenti e test può essere scaricato qui: PriorityExecutor .


Premio Web Italia 2010 16 July 2010


Xattenger.com è online! 28 April 2010

Gli utenti che da tempo usano il servizio di chat offerto dalla compagnia Xat sanno bene quanto restare connessi per più di dieci minuti possa essere frustrante.
Il problema è sempre lo stesso: il servizio è orientato ad un pubblico di bambini, con tutto ciò che di tragico ne consegue.
I comportamenti scorretti sono tenuto soprattutto da chi dovrebbe vigilare le chat e il baratto di xats (la moneta virtuale) o la promessa di poteri sono modi facili per corrompere gli utenti più immaturi.

Sfortunatamente Xat non offre strumenti adeguati per risolvere la situazione. Il problema è in realtà ben più insidioso, perché solitamente sono proprio questi gli utenti più propensi a pagare. Xat si trova quindi in una situazione critica, e non poco!

Per questo la speranza è che il progetto di XATtenger aiuti a mantenere un livello di ordine più accettabile. Gli utenti potranno creare bot tramite il sito, e programmarli per moderare le chat con le regole che riterranno più opportune. La capacità di personalizzazione sarà estremamente limitata, per evitare possibili usi scorretti dei bot o loro riprogrammazioni.

I bot non devono essere intesi come sostituiti dei moderatori umani, ma come un valido strumento di supporto alle chat. Anche di notte infatti possono garantire un livello di moderazione molto più tollerabile, evitando di creare milioni di moderatori che finiscono inevitabilmente per andare in conflitto tra loro.

Come sempre, il successo e il corretto uso del servizio di XATtenger rimane agli utenti finali.
Ed anche da come gestiranno questo potere si potrà capire meglio chi è responsabile, ma soprattutto chi non lo è.