Proseguo col repertorio di possibili opzioni per la progettazione di applicazioni multi-threading, da quelle comuni a entrambi i modelli a competizione e a sincronizzazione.
Quelli che hanno lo scopo di ridurre il tempo di lock di una istanza condivisa (= attraversata da più thread = i cui metodi sono richiamati da più thread) o la durata del rendezvous per una sincronizzazione tra produttore e consumatore.
Optimistick Locking
L'idea è la medesima di quella usata con i db, cioè quella di fare le elaborazioni e i calcoli lunghi prima ancora di mettere i lock o avviare il rendezvous per poi poter essere velocissimi dovendo solo applicare i risultati già calcolati e verificare che nel frattempo un altro thread non ha cambiato le carte in tavola.
L'ho trovato descritto nel Portland Pattern Repository http://c2.com/cgi/wiki?OptimisticLocking e anche da Fowler http://martinfowler.com/eaaCatalog/optimisticOfflineLock.html
Transazioni di compensazione
Questa idea arriva dai transaction processing monitor (come le Transactions e il DTC di COM+) e dalla teoria derivata dalle long running transaction, cioè lo studio delle caratteristiche di sistemi dove vengono rilassate alcune delle proprietà ACID delle transazioni.
L'idea è di spezzare il tempo di lock o di rendezvous in due parti in modo che una parte lunga di elaborazione che sta nel centro possa essere fatta senza lock o rendezvous. Se nella seconda parte l'esecuzione di controlli e veriifiche danno un risultato che invalida la prima parte, non essendo pià possibile annullarla (nel senso che nel fattempo quelle info sono state accessibili e potenzialmente giù utilizzate come buone da altri thread) si esegue una operazione uguale e contraria detta di compansazione.
Ho trovato qui una descrizione: http://en.wikipedia.org/wiki/Long-running_transaction
Double-check
Ossia il pattern del doppio controllo, uno prima di acquisire il lock o fare il rendezvous e uno durante a lock acquisito o a rendezvous in corso. E' utile quando il più delle volte il controllo da esito negativo e quindi non è necessario proseguire e fare effettivamente lock/rendezvous.
E' anche un anti pattern perchè la sua applicazione risente fortemente della architettura fisica del processore e dal linguaggio e quindi il codice compilato funziona diversamente da quanto si creda.
E' descritto nel Portland Pattern Repository http://c2.com/cgi/wiki?DoubleCheckedLocking e anche in wikipedia http://en.wikipedia.org/wiki/Double_checked_locking_pattern
Nel wiki di UGI http://wiki.ugidotnet.org/default.aspx/UGIdotNETWiki/PatternSingleton.html è descritta una implementazione che tiene conto della architettura del processore e del linguaggio ed è garantita di funzionare correttamente.
Read/write lock
Qui l'idea consiste nel permettere più letture contemporanee e invece restringere ad una scrittura alla volta riducendo di molto i casi in cui l'elaborazione di un thread resta bloccata in attesa che venga rilasciara un'istanza o in attesa dell'altra istanza produttore o consumatore con cui sincronizzarsi.
Anche questo è descritto nel Portland Pattern Repository http://c2.com/cgi/wiki?ReadWriteLock e in wikipedia http://en.wikipedia.org/wiki/Read_write_lock_pattern
Tags : Progettazione Software |