Bei normalen Instanzmethoden sind lokale Variablen Thread-sicher.
Wenn ich in einer statischen Methode folgendes habe:
%Vor%Wäre das Thread-sicher? Gibt es einen Haken?
Was genau bedeutet es auch, wenn jede Variable ihren eigenen Stack hat? Bedeutet das einen eigenen Stacktrace?
Danke
Wenn die von Ihnen geposteten Zeilen in der Methode enthalten sind, gibt es keinen Grund, warum es nicht threadsicher sein sollte. Die Threads interagieren in keiner Weise - jeder Thread sieht einen anderen i
.
Der Catch kommt, wenn Sie versuchen, den Wert von i zwischen Threads zu teilen, indem Sie beispielsweise i
zu einem statischen Feld machen. Dann ist es möglich, eine Rennbedingung zu erhalten, bei der Sie je nach Timing unterschiedliche Ergebnisse erhalten.
In Bezug auf Ihre zweite Frage hat jeder Thread einen eigenen Stack, nicht jede Variable.
Zunächst gehe ich davon aus, dass Sie sich mit "threadsafe" so verhalten, als ob bestimmte Operationen atomar sind, wenn Mutationen in mehreren Threads vorkommen. Wenn Sie das nicht mit "threadsafe" meinen, dann definieren Sie bitte sorgfältig "threadsafe", bevor Sie Fragen dazu stellen. Es scheint, dass fast jeder, der Fragen über Thread-Sicherheit bei Stack-Überlauf stellt, eine andere persönliche Definition für das hat, was es bedeutet.
Zweitens sind lokale Variablen nicht threadsafe . Insbesondere lokale Variablen, die abgeschlossene äußere Variablen einer Lambda-Methode oder anonymen Methode sind oder die sich innerhalb eines Iterator-Blocks befinden, sind nicht garantiert Thread-sicher, wenn sie auf mehreren Threads mutiert sind.
Lokale Variablen, die keine geschlossenen äußeren Variablen einer anonymen Funktion sind und sich nicht in einem Iteratorblock befinden, können nur vom aktuellen Thread mutiert werden und können daher nicht von mehreren Threads gleichzeitig mutiert werden.
>Was genau bedeutet es auch, wenn jede Variable ihren eigenen Stack hat?
Ich habe keine Ahnung, was das bedeutet; Variablen haben keine Stapel. Threads haben Stapel.
Kurze Antwort ist ja die folgende Methode ist threadsicher:
%Vor%Alle lokalen Variablen sind sicher, sofern sie nicht auf ein gemeinsames Objekt im Heap zeigen.
Genau wie bei Single-Thread-Anwendungen geben die folgenden Aufrufe dieser Methode unterschiedliche Werte zurück.
%Vor%Warum ist das? Weil jeder Aufruf der Methodennummer unterschiedliche Werte annimmt, und deshalb auch. Der Wert von i wird nicht gespeichert, nachdem die Funktion beendet ist, weil ich auf dem Stapel zugeordnet wurde. In fast allen Sprachen sind Funktionen Modell auf einem Stapel. Jedes Mal, wenn Sie eine andere Methode aufrufen, wird die aktuelle Methode angehalten. Eine neue Methode wird auf den Aufruf-Stack geschoben und aufgerufen. Wenn diese Methode beendet ist, pausiert das Programm die aufrufende Methode und setzt dort fort, wo es aufgehört hat (d. H. Bei der returnAddress). Jede lokale Variable, die in dieser Methode definiert ist, ist ein Teil des Stackframe der Methode. Der Stackframe für unsere obige Methode könnte folgendermaßen aussehen:
%Vor%Der Stapel könnte als eine Sammlung von StackFrame-Objekten betrachtet werden.
Stapel callStack
Jedes Mal, wenn eine neue Methode aufgerufen wird, kann das Programm etwa Folgendes tun:
%Vor%Was bedeutet das für Threading? Nun, im Falle von Threads hätten Sie mehrere unabhängige CallStacks mit ihrer eigenen Sammlung. Der Grund für den sicheren Zugriff auf lokale Variablen liegt darin, dass callStack von Thread 1 nicht auf den callStack von Thread 2 zugreifen kann, da es sich um separate Objekte handelt. Genau wie im Fall eines einzelnen Threads sind s und s2 verschiedene Objekte mit unterschiedlichen Zahlenwerten. Und so sind sie unabhängig voneinander. Stellen Sie sich vor, s ist in Thread 1 und s2 ist Thread 2. Thread 1 und Thread 2 teilen keine Speicher gemeinsam, so dass es threadsicher ist.
Threads geben ihre Stack-Frames nicht frei. Sie teilen sich den Haufen.