Sto espandendo i miei commenti in una risposta perché ritengo che alcuni aspetti del problema specifico vengano ignorati o utilizzati per trarre conclusioni sbagliate.
A questo punto, la domanda se il refactoring è prematuro (anche se probabilmente verrà data una risposta a una forma specifica di "sì").
Il problema centrale qui è che (come notato in alcune risposte) i commenti che citi indicano strongmente che il codice ha condizioni di competizione o altri problemi di concorrenza / sincronizzazione, come discusso qui . Questi sono problemi particolarmente difficili, per diversi motivi. Innanzitutto, come è stato rilevato, le modifiche apparentemente non correlate possono innescare il problema (altri bug possono avere questo effetto, ma quasi sempre gli errori di concorrenza fanno). In secondo luogo, sono molto difficili da diagnosticare: l'errore si manifesta spesso in un luogo che è distanti nel tempo o codice dalla causa, e qualsiasi cosa tu faccia per diagnosticare potrebbe farla andare via ( Heisenbugs ). In terzo luogo, i bug di concorrenza sono molto difficili da trovare nei test. In parte, ciò è dovuto all'esplosione combinatoria: è abbastanza grave per il codice sequenziale, ma aggiungendo i possibili intrecci di esecuzione simultanea si arriva al punto in cui il problema sequenziale diventa insignificante al confronto. Inoltre, anche un buon test può solo occasionalmente attivare il problema - Nancy Leveson ha calcolato che uno dei bug letali nel Therac 25 si è verificato in 1 di circa 350 sessioni, ma se non sai qual è il bug, o anche che ce ne sia uno, non sai quante ripetizioni facciano un test efficace. Inoltre, solo su questa scala è possibile eseguire solo test automatici, ed è possibile che il test driver imponga vincoli temporali minimi tali da non attivare mai il bug (Heisenbugs di nuovo).
Ci sono alcuni strumenti per il test della concorrenza in alcuni ambienti, come Helgrind per il codice usando i pthreads POSIX , ma non conosciamo le specifiche qui. I test dovrebbero essere integrati con analisi statiche (o viceversa?), Se esistono strumenti adeguati per il proprio ambiente.
Per aumentare la difficoltà, i compilatori (e persino i processori, in fase di esecuzione) sono spesso liberi di riorganizzare il codice in modi che a volte rendono il ragionamento sulla sicurezza del thread molto contro-intuitivo (forse il caso più noto è il Blocca con doppio controllo , anche se alcuni ambienti (Java, C ++ ...) sono stati modificati per migliorarlo. )
Questo codice potrebbe presentare un semplice problema che causa tutti i sintomi, ma è più probabile che tu abbia un problema sistemico che potrebbe portare i tuoi piani ad aggiungere nuove funzionalità. Spero di averti convinto che potresti avere un problema serio nelle tue mani, forse anche una minaccia esistenziale al tuo prodotto, e la prima cosa da fare è scoprire cosa sta succedendo. Se questo rivela problemi di concorrenza, ti consiglio vivamente di risolverli prima, prima ancora di porre la domanda se devi eseguire un refactoring più generale e prima di provare ad aggiungere altre funzionalità.