Hallo gugugs,
du hast nicht genau klar gemacht, WER die Funktion ein zweites mal aufruft.
Es gibt da ja die Möglichkeit, dass die Funktion#3, die Funktion#1 selbst wieder aufruft. Das wird dann als Rekursion bezeichnet.
Man verwendet das oft, um große Probleme zu lösen, indem man das Problem eine Stufe kleiner löst und dann das Ergebnis nur noch für die höhere Stufe anpasst (z.B. um n! zu berechnen, genügt es, (n-1)! zu kennen und mit n zu multiplizieren).
In diesem Fall, wird die Ausführung von Funktion#3 an dieser Stelle unterbrochen, bis der Aufruf von Funktion#1 beendet ist. Man muss aufpassen, dass keine Endlosschleifen entstehen, sondern es immer noch eine Situation gibt, in der die Rekursion abbricht.
Für die Valiablen bedeutet das: Variablen, die in der Funktion lokal deklariert wurden, werden mehrfach angelegt. Jede Instanz der Funktion erhält ihr eigenes Set an Variablen, die mit den Variablen der anderen Instanzen der Funktion nicht kollidieren.
Variablen, die außerhalb der Funktion deklariert wurden (z.B. Variablen der Klasse oder globale Variablen) existieren allerdings nur einmal. Du musst aufpassen, dass die verschiedenen Rekursionsstufen sich nicht gegenseitig die Ergebnisse kaputtmachen.
Veränderte globale Variablen werden auch als „Nebeneffekte“ von diesen Funktionen bezeichnet.
Die andere Möglichkeit ist es, wenn du Funktion von einem weiteren Thread ein weiteres Mal aufgerufen wird (z.B., indem du ein Fenster hast und zweimal auf einem Butten klickst, wodurch zwei Threads gestartet werden, die diese Funktion aufrufen).
Dieser Fall ist deutlich komplizierter, da du als Programmierer nicht wissen kannst, in welcher Reihenfolge die Funktionen aufgerufen werden und außerdem laufen die Funktionen quasi gleichzeitig nebeneinander.
Hier gilt wieder: lokale Variablen werden kopiert und existieren in jeder Instanz der Funktion einzeln, so dass sie sich nicht in die Quere kommen.
Globale Variablen existieren aber wieder übergreifend.
Du musst als Programmierer nicht nur sicherstellen, dass sich die einzelnen Funktionen nicht gegenseitig die Ergebnisse zerschießen, du musst auch darauf aufpassen, dass die Zustände in den eizelnen Funktionen konsistent bleiben.
Beispiel:
Funktion#1 durchläuft eine Liste.
Funktion #2 leert gleichzeitig die Liste
Funktion #1 versucht bei seinem Durchlauf das Element 1234 (das es eben noch gab) auszulesen -> Fehler!
Um solche Concurrency-Probleme zu vermeiden, werden Mechanisman eingesetzt, die man „Locking“ (versperren) nennt. Ein Thread kann ein Objekt sperren, so dass nur er damit arbeiten kann. Andere Threads, die dies ebenfalls manipulieren möchten, müssen warten, bis der Thread fertig ist.
Also, um deine Frage abschließend zu beantworten (ich vermute einfach mal, dass du den zweiten Fall, also Multithreading meinst):
Auch wenn der erste Ablauf von Funktion#3 noch nicht fertig ist, wird trotzdem gleichzeit eine neue Instanz von Funktion#1 gestartet.
Versuche, so viele Variablen wie möglich lokal zu halten (und über Funktionsparameter zu befüllen), dann werden diese einfach für jede Instanz neu erstellt und du hast kein Problem.
Wenn du auf globale Variablen zugreifen musst, solltest du besser eine Art Locking implementieren, sonst kriegst du Probleme.
Es macht einen guten Programmierer aus, dass er seine Programmabläufe so planen kann, dass diese Probleme so selten wie möglich auftreten können.
mfg, metax.