3 Stimmen

Synchronisationsprobleme mit einer statischen Methode in Java

Angenommen, ich habe eine Utility-Klasse,

public class Utility {

    private Utility() {} //Don't worry, just doing this as guarantee.

    public static int stringToInt(String s) {
        return Integer.parseInt(s);
    }
};

Nehmen wir nun an, in einer Multithread-Anwendung ruft ein Thread auf, Utility.stringToInt() Methode und während der Vorgang in den Methodenaufruf eintritt, ruft ein anderer Thread dieselbe Methode auf und übergibt eine andere s . Was geschieht in diesem Fall? Sperrt Java eine statische Methode?

10voto

Alex Gitelman Punkte 23929

Hier gibt es kein Problem. Jeder Thread verwendet seinen eigenen Stack, so dass es keinen Kollisionspunkt zwischen verschiedenen s . Und Integer.parseInt() ist thread-sicher, da es nur lokale Variablen verwendet.

3voto

Edwin Buck Punkte 67237

Java sperrt eine statische Methode nicht, es sei denn, Sie fügen das Schlüsselwort synchronized .

Beachten Sie, dass Sie beim Sperren einer statischen Methode die Mutex des Klassenobjekts, unter dem die Methode implementiert ist, ergreifen, so dass die Synchronisierung einer statischen Methode andere Threads daran hindert, eine der anderen "synchronisierten" statischen Methoden aufzurufen.

In Ihrem Beispiel brauchen Sie in diesem speziellen Fall nicht zu synchronisieren. Das liegt daran, dass die Parameter per Kopie übergeben werden; mehrere Aufrufe der statischen Methode führen also zu mehreren Kopien der Parameter, jede in ihrem eigenen Stackframe. Gleichermaßen führen gleichzeitige Aufrufe von Integer.parseInt(s) erstellen jeweils ihren eigenen Stack-Frame, wobei Kopien des Wertes von s in die einzelnen Stack-Frames übertragen werden.

Wenn nun Integer.parseInt(...) auf eine sehr schlechte Art und Weise implementiert wurde (es wurden statische nicht-finale Mitglieder während der Ausführung von parseInt verwendet), dann gäbe es einen großen Grund zur Sorge. Glücklicherweise sind die Implementierer der Java-Bibliotheken bessere Programmierer als das.

1voto

Peter Lawrey Punkte 511323

In dem von Ihnen angeführten Beispiel gibt es keine gemeinsamen Daten zwischen Threads UND keine Daten, die geändert werden. (Sie müssten beides haben, damit ein Threading-Problem vorliegt)


Sie können schreiben

public enum Utility {
    ; // no instances

    public synchronized static int stringToInt(String s) {
        // does something which needs to be synchronised.
    }
}

ist dies praktisch dasselbe wie

public enum Utility {
    ; // no instances

    public static int stringToInt(String s) {
        synchronized(Utility.class) {
            // does something which needs to be synchronised.
        }
    }
}

wird die Methode jedoch nicht als synchronisiert gekennzeichnet, und Sie brauchen keine Synchronisierung, es sei denn, Sie greifen auf gemeinsam genutzte Daten zu, die geändert werden können.

0voto

Nrj Punkte 6513

Dies sollte nicht der Fall sein, es sei denn, es wird ausdrücklich angegeben. Außerdem gibt es in diesem Fall kein Problem mit der Threadsicherheit, da "s" unveränderlich und auch lokal für die Methode ist.

0voto

Suraj Chandran Punkte 23973

Sie brauchen hier keine Synchronisierung, da die Variable s ist lokal.

Sie müssen sich nur Sorgen machen, wenn mehrere Threads Ressourcen gemeinsam nutzen, z. B. wenn s war ein statisches Feld, dann muss man über Multithreading nachdenken.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X