2016-06-27 7 views
5

Ich würde gerne wissen, ob Thread-Sicherheit bereits eine Rolle spielt bei der Handhabung von Parametern von Mitgliedern in Java.Thread-Sicherheit der Methodenparameter in Java

Sagen Sie bitte eine Methode eines API

boolean moreThanTen(long value) { 
    if(value > 10) return true; 
    else return false; 
} 

würde diese Methode sicher Thread haben?

Ich denke, es wäre da jeder Thread hat einen eigenen Stapel für lokale Variablen, und Grundelemente sind alle in diesem lokalen Stapel gespeichert.

Das einzige, was mich unsicher macht, ist die Tatsache, dass ein long zwei separate Lesevorgänge und somit im Allgemeinen nicht threadsicher ist.

Meine Frage ist: Kann ich sicher sein, dass der Parameter einer Methode atomar kopiert wird? Wenn ich also ein Grundelement als Parameter verwende (auch float/long), kann ich sicher sein, dass beim Kopieren auf eine lokale Variable die Thread-Sicherheit kein Problem ist?

Danke.

+3

Das Fehlen eines veränderbaren Zustands impliziert, dass die Methode threadsicher ist. – Andreas

Antwort

8

Um nicht sicher zu sein, muss eine Methode mehreren Threads erlauben, auf freigegebene Ressourcen zuzugreifen (z. B. ein Feld).

In Ihrem Beispiel gibt es keine freigegebenen Ressourcen (Java übergibt Argumente nach Wert), so dass die Methode nicht unsicher sein kann.

würde dies eine unsichere, weil threshold von mehr als einem Thread zugänglich ist, und greift auf die Variable nicht korrekt synchronisiert:

  • ein Thread die threshold Variable lesen werden kann, während es ist von einem anderen Thread aktualisiert, was zu einem inkonsistenten Lesen führen kann (long writes are not guaranteed to be atomic); und
  • ein Schreiben in die threshold Variable von einem Thread möglicherweise nicht aus einem anderen Thread aufgrund der fehlenden Synchronisierung sichtbar, was dazu führen kann, dass der zweite Thread einen veralteten Wert lesen.
private long threshold; //mutable, may change 

boolean moreThanThreshold(long value) { 
    return value > threshold; //side comment: cleaner than your if/else 
} 
void setThreshold(long t) { this.threshold = t; } 
+0

Ihr Beispiel ist Thread-sicher, da einzelne Lese- und Schreibvorgänge atomar sind. Sie haben ein Sichtbarkeitsproblem festgestellt, das durch Verwendung von volatile behoben werden kann, wodurch auch das Aufreißen von Wörtern beseitigt wird (bei JLS-kompatiblen JVMs) – xTrollxDudex

+0

Wenn es ein Sichtbarkeitsproblem gibt, ist die Methode definitionsgemäß nicht threadsicher. Darüber hinaus ist ein langer Schreibvorgang garantiert nicht atomar durch die JLS. – assylias

+0

Ein * volatile * long write ist – xTrollxDudex

1

Keine Probleme Einfädeln in diesem Fall .. alles liest geschieht in der eigenen Stack Methoden. Kurz gesagt, obwohl sie zwei Lesevorgänge sind .. sie geschehen auf einem Wert innerhalb des Stapels, der nicht unter anderen Threads geteilt wird.

Hier ist etwas detaillierter, warum zwei Lesevorgänge kein Problem sind.

Bei der Übergabe von Argumenten an eine Methode übergeben wir NICHT die Referenzvariable, sondern eine Kopie der Bits in der Referenzvariablen. So etwas wie: 3bad086a. 3bad086a stellt eine Möglichkeit dar, zum übergebenen Objekt zu gelangen. Wir übergeben gerade 3bad086a, dass es der Wert der Referenz ist. Wir übergeben den Wert der Referenz und nicht die Referenz selbst (und nicht das Objekt). Dieser Wert wird tatsächlich kopiert und an die Methode übergeben. Wir übergeben immer eine Kopie der Bits des Wertes der Referenz! Wenn es sich um einen primitiven Datentyp handelt, enthalten diese Bits den Wert des primitiven Datentyps selbst. Wenn es ein Objekt ist, enthalten die Bits den Wert der Adresse, die der JVM mitteilt, wie sie zum Objekt gelangt.

Verwandte Themen