Ich erweitere meine Kommentare zu einer Antwort, weil ich denke, dass einige Aspekte des spezifischen Problems entweder übersehen werden oder verwendet werden, um die falschen Schlussfolgerungen zu ziehen.
Zu diesem Zeitpunkt ist die Frage, ob eine Refaktorisierung durchgeführt werden soll, verfrüht (auch wenn dies wahrscheinlich durch ein bestimmtes Ja beantwortet wird).
Das zentrale Problem hierbei ist, dass (wie in einigen Antworten erwähnt) die von Ihnen zitierten Kommentare nachdrücklich darauf hinweisen, dass der Code Race-Bedingungen oder andere Parallelitäts- / Synchronisationsprobleme aufweist, wie hier beschrieben . Dies sind aus mehreren Gründen besonders schwierige Probleme. Erstens können, wie Sie festgestellt haben, scheinbar nicht zusammenhängende Änderungen das Problem auslösen (andere Fehler können ebenfalls diesen Effekt haben, aber Parallelitätsfehler sind fast immer der Fall.) Zweitens sind sie sehr schwer zu diagnostizieren: Der Fehler manifestiert sich häufig an einem Ort, an dem er sich befindet Zeit oder Code von der Ursache entfernt, und alles, was Sie tun, um sie zu diagnostizieren, kann dazu führen, dass sie verschwindet ( Heisenbugs). Drittens sind Parallelitätsfehler beim Testen sehr schwer zu finden. Dies liegt zum Teil an der kombinatorischen Explosion: Sie ist für sequentiellen Code schon schlimm genug, aber das Hinzufügen der möglichen Verschachtelungen der gleichzeitigen Ausführung führt dazu, dass das sequentielle Problem im Vergleich dazu nicht mehr von Bedeutung ist. Darüber hinaus kann selbst ein guter Testfall das Problem nur gelegentlich auslösen - Nancy Leveson errechnete, dass einer der tödlichen Fehler im Therac 25 isttrat in 1 von ungefähr 350 Läufen auf, aber wenn Sie nicht wissen, was der Fehler ist, oder sogar, dass es einen gibt, wissen Sie nicht, wie viele Wiederholungen einen wirksamen Test durchführen. Darüber hinaus ist in diesem Maßstab nur ein automatisiertes Testen möglich, und es ist möglich, dass der Testtreiber subtile zeitliche Einschränkungen auferlegt, so dass er den Fehler nie mehr auslöst (Heisenbugs again).
In einigen Umgebungen gibt es einige Tools zum Testen der Parallelität, z. B. Helgrind für Code unter Verwendung von POSIX-Pthreads. Wir kennen die Details hier jedoch nicht. Das Testen sollte durch eine statische Analyse ergänzt werden (oder ist das umgekehrt?), Wenn es geeignete Tools für Ihre Umgebung gibt.
Um die Schwierigkeit zu erhöhen, können Compiler (und sogar die Prozessoren zur Laufzeit) den Code oft auf eine Weise reorganisieren, die es manchmal unmöglich macht, über die Threadsicherheit nachzudenken (vielleicht ist der bekannteste Fall die doppelte Überprüfung) sperren Sie Idiom, obwohl einige Umgebungen (Java, C ++ ...) geändert worden sind, um es zu verbessern.)
Dieser Code kann ein einfaches Problem haben, das alle Symptome verursacht, aber es ist wahrscheinlicher, dass Sie ein systembedingtes Problem haben, das Ihre Pläne, neue Funktionen hinzuzufügen, zum Erliegen bringen könnte. Ich hoffe, ich habe Sie überzeugt, dass Sie möglicherweise ein ernstes Problem in Ihren Händen haben, möglicherweise sogar eine existenzielle Bedrohung für Ihr Produkt, und das erste, was Sie tun müssen, ist herauszufinden, was passiert. Wenn dies Parallelitätsprobleme aufzeigt, rate ich Ihnen dringend, diese zuerst zu beheben, bevor Sie sich überhaupt die Frage stellen, ob Sie allgemeinere Umgestaltungen vornehmen sollten, und bevor Sie versuchen, weitere Funktionen hinzuzufügen.