webentwicklung-frage-antwort-db.com.de

Sind nicht synchronisierte statische Methoden threadsicher, wenn sie keine statischen Klassenvariablen ändern?

Ich habe mich gefragt, ob Sie eine statische Methode haben, die nicht synchronisiert ist, aber nicht statische Variablen modifiziert, ist sie thread-sicher? Was ist, wenn die Methode lokale Variablen darin erstellt? Ist der folgende Code beispielsweise threadsicher?

public static String[] makeStringArray( String a, String b ){
    return new String[]{ a, b };
}

Wenn ich also zwei Threads habe, die diese Methode kontinuierlich und gleichzeitig aufrufen, wird einer mit Hunden (sagen wir "Deutsche Dogge" und "Bulldogge") und der andere mit Katzen (sagen wir "Perser" und "Siamese") jemals Katzen und Hunde bekommen im selben Array? Oder werden sich die Katzen und Hunde niemals gleichzeitig im selben Aufruf der Methode befinden?

143
Tobogganski

Diese Methode ist zu 100% threadsicher, selbst wenn es nicht static wäre. Das Problem mit der Thread-Sicherheit tritt auf, wenn Sie Daten zwischen Threads austauschen müssen - Sie müssen auf Atomizität, Sichtbarkeit usw. achten.

Diese Methode funktioniert nur mit Parametern, die sich auf dem Stapel befinden und Verweisen auf unveränderliche Objekte auf dem Heap. Stack ist inhärent lokal für den Thread, daher findet niemals eine gemeinsame Nutzung von Daten statt.

Unveränderliche Objekte (in diesem Fall String) sind auch threadsicher, da sie nach ihrer Erstellung nicht geändert werden können und alle Threads denselben Wert sehen. Andererseits, wenn die Methode Date akzeptiert (veränderlich), könnten Sie ein Problem gehabt haben. Zwei Threads können gleichzeitig dieselbe Objektinstanz ändern, was zu Race-Bedingungen und Sichtbarkeitsproblemen führt.

207

Eine Methode kann nur thread-unsicher sein, wenn sie einen gemeinsam genutzten Status ändert. Ob es statisch ist oder nicht, spielt keine Rolle.

28
Konrad Garus

Die Funktion ist absolut threadsicher.

Wenn Sie darüber nachdenken ... nehmen Sie an, was passieren würde, wenn dies anders wäre. Jede gewöhnliche Funktion hätte Threading-Probleme, wenn sie nicht synchronisiert wäre. Daher müssten alle API-Funktionen im JDK synchronisiert werden, da sie möglicherweise von mehreren Threads aufgerufen werden könnten. Und da die App meistens eine API verwendet, sind Multithread-Apps praktisch unmöglich.

Das ist zu lächerlich, um darüber nachzudenken, also nur für Sie: Methoden sind nicht threadsicher, wenn es einen klaren Grund gibt, warum es Probleme geben könnte. Versuchen Sie immer darüber nachzudenken, was passiert, wenn in meiner Funktion mehrere Threads vorhanden sind, und wenn Sie einen Step-Debugger haben und einen Step nach dem anderen den ersten ... dann den zweiten Thread ... vielleicht den zweiten erneut ... würde es probleme geben Wenn Sie eines finden, ist es nicht threadsicher.

Beachten Sie auch, dass die meisten der Java 1.5 Collection-Klassen nicht threadsicher sind, mit Ausnahme der angegebenen Klassen wie ConcurrentHashMap.

Und wenn Sie wirklich darauf eingehen möchten, schauen Sie sich das volatile Keyword und ALLE seine Nebenwirkungen genau an. Schauen Sie sich die Klassen Semaphore () und Lock () sowie deren Freunde in Java.util.Concurrent an. Lesen Sie alle API-Dokumente zu den Klassen. Es lohnt sich zu lernen und auch zu befriedigen.

Entschuldigen Sie diese überaus aufwändige Antwort.

12
Daniel

Verwenden Sie das Schlüsselwort static mit synchronisierten statischen Methoden, um statische Daten zu ändern, die von Threads gemeinsam genutzt werden. Mit dem Schlüsselwort static konkurrieren alle erstellten Threads um eine einzelne Version der Methode.

Wenn Sie das Schlüsselwort volatile zusammen mit synchronisierten Instanzmethoden verwenden, wird sichergestellt, dass jeder Thread über eine eigene Kopie der freigegebenen Daten verfügt und zwischen den Threads keine Lese-/Schreibvorgänge auftreten.

1
clinton

Die Unveränderlichkeit von Zeichenfolgenobjekten ist ein weiterer Grund für das oben beschriebene threadsichere Szenario. Wenn stattdessen veränderbare Objekte verwendet werden (sagen wir makeMutableArray ..), wird die Threadsicherheit mit Sicherheit unterbrochen.

0
harsh