Nach Jahren des Formularausfüllens und Wartens hast du endlich deine Banklizenz erworben. Das heißt, du bist jetzt offiziell berechtigt, deine eigene Bank zu eröffnen, hurra!
Deine erste Priorität ist es, die IT-Systeme ans Laufen zu bringen. Nach einem Tag harter Arbeit kannst du bereits Konten eröffnen und schließen sowie Abhebungen und Einzahlungen bearbeiten.
Da du keine Lust hattest, Tests zu schreiben, bittest du ein paar Freunde, dir beim Testen des Systems zu helfen. Doch schon nach fünf Minuten behauptet einer deiner Freunde, Geld verloren zu haben! Du bist dir zwar sicher, dass dein Code fehlerfrei ist, doch du fängst an, die Logs zu durchsuchen, um der Sache nachzugehen.
Ah ja, genau wie du vermutet hast, ist dein Freund schuld! Einer deiner Freunde hat seine Test-Zugangsdaten mit einem anderen Freund geteilt, und gemeinsam haben sie sich verschworen, vom selben Konto parallel Einzahlungen und Abhebungen vorzunehmen. Wer würde so etwas tun?
Während du argumentierst, es sei physisch unmöglich, dass jemand parallel auf sein Konto zugreift, teilt dein Freund dir selbstgefällig mit, dass die Bankregeln verlangen, dass du das unterstützt. Also: keine parallele Unterstützung fürs Banking, keine Freigabe für den Livegang. Seufzend machst du dir eine mentale Notiz, dich morgen darum zu kümmern. Das verschiebt deinen Starttermin um mindestens einen weiteren Tag, aber nun ja...
Deine Aufgabe ist es, Bankkonten zu implementieren, die das Eröffnen und Schließen sowie Abhebungen und Einzahlungen von Geld unterstützen.
Da auf Bankkonten auf viele verschiedene Arten zugegriffen werden kann (Internet, Mobiltelefone, automatische Abbuchungen), muss deine Banksoftware es ermöglichen, dass mehrere Threads/Prozesse (die Terminologie hängt von deiner Programmiersprache ab) parallel und sicher auf Konten zugreifen. Zum Beispiel kann es viele Einzahlungen und Abhebungen geben, die parallel ablaufen; du musst sicherstellen, dass zwischen dem Lesen des Kontostands und dem Setzen des neuen Kontostands keine Race Conditions auftreten.
Es sollte möglich sein, ein Konto zu schließen; Operationen auf einem geschlossenen Konto müssen fehlschlagen.
In dieser Übung lernst du die Nebenläufigkeit kennen.
Um den letzten Test zu bestehen, könnten dir das synchronized-Schlüsselwort oder Locks nützlich sein.
Probleme, die beim gleichzeitigen Ausführen von Code auftreten, sind oft nur sporadisch, weil sie von der Reihenfolge abhängen, in der der Code ausgeführt wird. Deshalb führt der letzte Test viele Threads mehrmals aus, um die Chance zu erhöhen, einen Fehler zu finden. Das bedeutet, dieser Test sollte fehlschlagen, wenn deine Implementierung nicht threadsicher ist. Es kann aber vorkommen, dass er nur deshalb besteht, weil es keinen Versuch einer gleichzeitigen Änderung gab. Es ist unwahrscheinlich, dass das mehrmals hintereinander passiert, denn die Reihenfolge, in der der Code ausgeführt wird, sollte sich bei jedem Testlauf ändern. Wenn du den letzten Test also ein paar Mal ausführst und er jedes Mal besteht, kannst du ziemlich sicher sein, dass deine Implementierung korrekt ist.
Melde dich bei Exercism an, um Java mit 26 Konzepte158 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.