Come la maggior parte dei programmatori, sono cosciente dei rischi nei quali si incorre in un ambiente multithreading. Per me come per altri del mestiere, termini come race-condition, concurrency, e deadlock, sono pane quotidiano. So ad esempio che in buon senso consiglia che un lock() duri il meno possibile per evitare che altri thread concorrenti rimangano bloccati in attesa e si verifichi un degrado delle prestazioni.

Mai però mi sarei aspettato di averne la prova nel mondo "reale", proprio sulla mia pelle. Mi spiego: stamane sono stato in posta, per ritirare un pacco che veniva da Amazon e mi sono imbattuto nel nuovissimo e fiammante sistema di gestione delle code. Bello e molto ben fatto. Una macchinetta riceve gli utenti all'ingresso e solerte gli fornisce un numerello che poi "prima o poi" appare sul display che sovrasta ogni sportello.

Il problema sta proprio nel "prima o poi". Chiunque ha ben presente la vecchina che si presenta allo sportello per fare un vaglia; si mette in coda, arriva il suo turno, l'impiegato si accorge che la vecchina non ha compilato il modulo quindi gli spiega in due parole come si compila e poi passa all'utente successivo, mentre il "thread-vecchina" compila il modulo.

Il nuovo sistema invece fa sì che l'utente ponga un lock esclusivo sullo sportello, perciò tutti "thread-utente" rimangono inutilmente in attesa che il "thread-vecchina" compili il modulo mentre il "thread-impiegato-dello-sportello" la guarda senza fare nulla.

lock( sportello )
{
   Modulo vaglia = impiegato.ConsegnaModulo();

   impiegato.AttendiEConversaConLoSportelloAdiacente();
  
   while( !vaglia.IsCorretto )
       vecchina.Compila( vaglia );

   impiegato.EseguiVaglia();

   impiegato.AttendiEConversaConLoSportelloAdiacente();

   vecchina.ContaISoldi();

   Pagamento pag = impiegato.RiceviContanteDa( vecchina );
   impiegato.AttendiEConversaConLoSportelloAdiacente();

   Ricevuta ric = vecchina.RitiraRicevutaDa( impiegato );

   impiegato.SalutaAmabilmenteLaVecchina();
}

Vi lascio immaginare che genere di attività svolgono nel frattempo i "thread-utente" in attesa. (utente.Impreca() è molto gettonato). Comunque questo dimostra quanto una pessima politica di gestione della concorrenza possa impattare sulle performance di un'attività.

10 persone in coda = 1 ora abbondante.