Heim >Java >javaLernprogramm >Lernartikel: Informationen zur Synchronisierung in Java

Lernartikel: Informationen zur Synchronisierung in Java

php是最好的语言
php是最好的语言Original
2018-08-09 16:48:442087Durchsuche

Bei unserer täglichen Entwicklungsarbeit sind wir mehr oder weniger Multithread-Programmierung oder einigen Parallelitätsproblemen ausgesetzt. Mit der Aktualisierung von Betriebssystemen und Systemhardware wird in unserer Entwicklung zunehmend gleichzeitige Programmierung verwendet Die Verwendung von Multithreading dient dazu, die Systemressourcen besser zu nutzen. Wenn wir jedoch Multithreading verwenden, treten zunächst einige Probleme auf.

    private static int i = 0;

    private static void increse(){
        i++;
    }

    public static void main(String[] args) {
    Thread[] threads = new Thread[20];
        for (int i = 0; i < threads.length; i++){
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 10000; j++){
                        increse();
                    }
                }
            });
            threads[i].start();
        }
        
        while (Thread.activeCount() > 1){
            Thread.yield();
        }
        
        System.out.println(i);
    }

Zuallererst gibt es kein Problem, wenn Sie sich diesen Code ansehen, aber wenn er sich in einer Multithread-Umgebung befindet, sind die Ergebnisse der Ausführung dieses Codes grundsätzlich unterschiedlich. Hier werden 20 Threads gestartet. und dann ruft jeder Thread die Methode increse() auf, um eine Zuweisungsoperation für die Variable i durchzuführen. Die erwartete Ausgabe sollte 200000 sein, aber warum ist die Ausgabe jedes Mal anders? Der Grund liegt in diesem Ort i++ Dies ist die Hauptursache für Parallelitätsprobleme. Warum gibt es bei diesem scheinbar einfachen i++ ein solches Problem? Lassen Sie es uns einfach anhand von java内存模型(JMM) verstehen. Erstens legt JMM fest, dass jeder Thread beim Ausführen einen Arbeitsspeicher hat, und dann wird die Variable i jedes Mal im Hauptspeicher gespeichert Um es einfach auszudrücken: Nachdem ein Thread die Variable i berechnet und das Ergebnis erhalten hat, wurden die Daten nicht im Hauptspeicher aktualisiert Diesmal wurde der ursprüngliche Wert von anderen Threads abgerufen. Mit anderen Worten, es ist nicht bekannt, ob die in diesem Thread erhaltenen Daten die neuesten sind. Dies ist jedoch nur eine kurze Erklärung aus der Perspektive von JMM. Diese scheinbar einfache Operation von i++ enthält tatsächlich drei Operationen: Ermitteln des Werts von i, Erhöhen von i und Erhöhen von i . Während dieser Vorgänge haben andere Threads viel Zeit, um viele Dinge zu erledigen. Dann fragen sich einige Leute vielleicht, ob es ausreicht, diesen i++-Vorgang zu synchronisieren. Ja, wie synchronisiert man es?

Einige Leute sagen, dass es ausreicht, volatile zum Ändern der Variablen i zu verwenden? Ja, das Schlüsselwort java in volatile bietet zwar eine Synchronisierungsfunktion, aber warum hat eine Änderung hier immer noch keine Auswirkung? Der Grund dafür ist, dass, wenn eine Variable mit volatile geändert wird, es anderen Threads nur ermöglicht, den Wert der aktuellen Variablen sofort zu kennen. Dies wird als 可见性 bezeichnet, aber es kann die Probleme der i++-Operationen immer noch nicht lösen Was? Um damit umzugehen, hat jemand anderes vorgeschlagen, das Schlüsselwort synchronized zu verwenden. Ich muss zugeben, dass dieses Schlüsselwort tatsächlich sehr mächtig ist und dieses Problem lösen kann ? Das heißt, um es einfach auszudrücken: synchronized gehört zur JVM-Ebene. Methoden oder Codeblöcke mit diesem Schlüsselwort werden letztendlich als monitorenter und monitorexit interpretiert 🎜> Geben Sie Parameter ein, um das Objekt anzugeben, das gesperrt oder entsperrt werden soll, etwa so: reference

public synchronized String f(){
    //code
}

synchronized(object){
    //code
}

Wenn wir das sehen, sollten wir verstehen, warum

das Problem des oben genannten Programms lösen kann, aber wir sollten es auch tun Eines klarstellen Das Konzept ist synchronized Mit anderen Worten: Wenn wir uns mit einigen Multithread-Problemen befassen, sollten wir sicherstellen, dass einige Operationen an gemeinsam genutzten Daten atomar sind, um die Korrektheit sicherzustellen Wenn Sie eine Idee haben, fassen wir zusammen, welche Punkte beim Umgang mit Multithreading-Problemen zu beachten sind. 原子性, 可见性, 原子性 Diese Punkte sind eine Voraussetzung, um sicherzustellen, dass Multithreading korrekt sein kann. Was Ordnung betrifft, geht es um die Neuordnung von Speicheranweisungen, die nicht Gegenstand der Diskussion ist. Wir werden später darauf eingehen. 有序性

Ich möchte hier auch auf ein anderes Problem hinweisen, nämlich ob wir bei Multithreading-Problemen synchronisieren oder sperren müssen. Das ist nicht sicher, wann Wenn wir uns mit Multithread-Problemen befassen, stellen wir manchmal fest, dass der Code als Single-Threaded geschrieben ist. Das ist natürlich nur ein Scherz, aber hier können wir auch sehen, ob Single-Threaded-Programme diese Frage nicht haben. Die Antwort lautet „Ja“, da es in einem einzelnen Thread kein Ressourcenkonkurrenzproblem gibt und es daher nicht erforderlich ist, es erneut zu diskutieren.

Wann müssen wir also die Synchronisierung verwenden und wann nicht? Werfen wir einen Blick auf einen Codeabschnitt

    public String f(String s1, String s2, String s3){
        return s1 + s2 +s3;
    }

Dies ist eine Methode zum Spleißen von Zeichenfolgen. Schauen wir uns an, wie die JVM das hier macht.

Verwandte Empfehlungen:


Detaillierte Erläuterung der Java-Thread-Synchronisation und Synchronisationsmethoden

Detaillierte Einführung in den synchronisierten Block des Java-Synchronisationsblocks Verwenden Sie

Das obige ist der detaillierte Inhalt vonLernartikel: Informationen zur Synchronisierung in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn