Heim  >  Artikel  >  Java  >  Java-Threads und gemeinsam genutzte Ressourcen

Java-Threads und gemeinsam genutzte Ressourcen

黄舟
黄舟Original
2017-02-28 10:37:291514Durchsuche

Code, der sicher ist, wenn er von mehreren Threads gleichzeitig aufgerufen wird, wird als Thread-Sicherheit bezeichnet. Wenn ein Codeabschnitt threadsicher ist, enthält er keine Race Conditions. Race-Bedingungen treten nur auf, wenn mehrere Threads gemeinsam genutzte Ressourcen aktualisieren. Daher ist es wichtig zu wissen, wann Java-Threads gemeinsam genutzte Ressourcen ausführen.

Lokale Variablen

Lokale Variablen werden im eigenen Stapel jedes Threads gespeichert. Das bedeutet, dass lokale Variablen nicht von Threads gemeinsam genutzt werden. Das bedeutet auch, dass alle lokalen primitiven Variablen threadsicher sind. Hier ist ein Beispiel:


public void someMethod(){

  long threadSafeInt = 0;

  threadSafeInt++;
}


Lokale Objektreferenz


Lokale Verweise auf Objekte sind etwas anders. Die Referenz selbst wird nicht weitergegeben. Ein Verweis auf dieses Objekt kann jedoch nicht auf dem Stapel jedes Threads gespeichert werden. Alle Objekte werden im Shared Heap gespeichert.

Ein lokal erstelltes Objekt ist threadsicher, wenn es der Methode, in der es erstellt wurde, nicht entkommt. Tatsächlich können Sie es auch an andere Methoden übergeben, solange die Methoden des übergebenen Objekts nicht für andere Threads verfügbar sind.

Hier ist ein Beispiel:


public void someMethod(){

  LocalObject localObject = new LocalObject();

  localObject.callMethod();
  method2(localObject);
}

public void method2(LocalObject localObject){
  localObject.setValue("value");
}


Die LocalObject-Instanz in diesem Beispiel kann nicht von dieser Methode abgerufen werden Wird zurückgegeben und kann nicht an andere Objekte übergeben werden. Darauf kann von außerhalb der someMethod-Methode zugegriffen werden. Jeder Thread, der die Methode someMethod ausführt, erstellt seine eigene LocalObject-Instanz und weist sie der localObject-Referenz zu. Daher ist diese Verwendung threadsicher.

Tatsächlich ist die gesamte someMethod-Methode threadsicher. Auch wenn diese localObject-Instanz als Parameter an andere Methoden derselben Klasse oder anderer Klassen übergeben wird, ist ihre Verwendung threadsicher.

Die einzige Ausnahme besteht natürlich darin, dass eine dieser Methoden mit einem LocalObject als Argument aufgerufen wird, wodurch die LocalObject-Instanz auf irgendeine Weise gespeichert wird und der Zugriff von anderen Threads ermöglicht wird.

Objektmitgliedsvariablen

Objektmitgliedsvariablen (Felder) werden zusammen mit dem Objekt auf dem Heap gespeichert. Wenn also zwei Threads eine Methode für dieselbe Objektinstanz aufrufen und diese Methode die Objektmitgliedsvariablen aktualisiert, ist die gesamte Methode nicht threadsicher. Hier ist ein Beispiel:


public class NotThreadSafe{
    StringBuilder builder = new StringBuilder();

    public add(String text){
        this.builder.append(text);
    }
}


Wenn zwei Threads die Add-Methode gleichzeitig auf derselben NotThreadSafe-Instanz aufrufen, führt dies zu einer Race-Bedingung. Beispiel:



NotThreadSafe sharedInstance = new NotThreadSafe();

new Thread(new MyRunnable(sharedInstance)).start();
new Thread(new MyRunnable(sharedInstance)).start();

public class MyRunnable implements Runnable{
  NotThreadSafe instance = null;

  public MyRunnable(NotThreadSafe instance){
    this.instance = instance;
  }

  public void run(){
    this.instance.add("some text");
  }
}


Beachten Sie, dass die beiden MyRunnable-Instanzen dieselbe NotThreadSafe-Instanz verwenden. Daher tritt eine Race-Bedingung auf, wenn sie die Add-Methode aufrufen.


Wenn jedoch zwei Threads die Add-Methode gleichzeitig auf verschiedenen Instanzen aufrufen, führt dies nicht zu einer Race-Bedingung. Hier ist ein Beispiel aus dem vorherigen, leicht modifiziert:


new Thread(new MyRunnable(new NotThreadSafe())).start();
new Thread(new MyRunnable(new NotThreadSafe())).start();

Jetzt hat jeder Thread seine eigene NotThreadSafe-Instanz, sodass sie diese add-Methoden nennen und sich nicht gegenseitig stören . Dieser Code hat keine Rennbedingungen. Selbst wenn ein Objekt nicht threadsicher ist, kann es dennoch auf diese Weise verwendet werden, ohne dass es zu einer Racebedingung kommt.

Thread-Control-Überlaufregeln

Wenn Sie entscheiden möchten, ob der Zugriff Ihres Codes auf eine Ressource threadsicher ist, können Sie die folgenden Regeln verwenden :


If a resource is created, used and disposed within
the control of the same thread,
and never escapes the control of this thread,
the use of that resource is thread safe.


Eine Ressource kann jede gemeinsam genutzte Ressource sein, wie ein Objekt, Array, eine Datei, eine Datenbankverbindung, ein Socket usw. In Java können Sie ein Objekt nicht immer explizit zerstören. „Zerstört“ bedeutet also, dass das Objekt fehlt oder einen Nullverweis hat.


Auch wenn die Verwendung eines Objekts threadsicher ist und dieses Objekt auf eine gemeinsam genutzte Ressource wie eine Datei oder Datenbank verweist, ist Ihre Anwendung als Ganzes möglicherweise nicht sicher Thread-sicher. Wenn beispielsweise Thread 1 und Thread 2 jeweils ihre eigenen Datenbankverbindungen erstellen, sind Verbindung 1 und Verbindung 2, die jeweils ihre eigene Verbindung verwenden, threadsicher. Die Verwendung der Datenbank, auf die diese Verbindung verweist, ist jedoch möglicherweise nicht threadsicher. Wenn beispielsweise zwei Threads Code wie diesen ausführen:


check if record X exists
if not, insert record X


Wenn zwei Threads dies gleichzeitig ausführen und diesen Datensatz überprüfen, besteht hier ein Risiko dass sie am Ende alle in denselben Datensatz eingefügt werden. Wie unten gezeigt:

Thread 1 checks if record X exists. Result = no
Thread 2 checks if record X exists. Result = no
Thread 1 inserts record X
Thread 2 inserts record X


Dies geschieht auch bei Threads, die Dateien oder andere gemeinsam genutzte Ressourcen bearbeiten. Daher ist es wichtig zu unterscheiden, ob es sich bei einem von einem Thread gesteuerten Objekt um eine Ressource oder lediglich um einen Verweis auf diese Ressource (wie eine Datenbankverbindung) handelt.

Das Obige ist der Inhalt von Java-Threads und gemeinsam genutzten Ressourcen. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn).


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