wake-up-neo.com

Ist es sinnvoll, auf lokale Variable zu synchronisieren?

Aus dem Java-Speichermodell wissen wir, dass jeder Thread seinen eigenen Thread-Stapel hat und dass lokale Variablen in den eigenen Thread-Stapel jedes Threads gestellt werden.

Und dieser andere Thread kann nicht auf diese lokalen Variablen zugreifen.

In welchem ​​Fall sollten wir also lokale Variablen synchronisieren?

8
NingLee

Es gibt zwei Situationen:

  1. Die lokale Variable hat einen primitiven Typ wie int oder double.
  2. Die lokale Variable hat einen Referenztyp wie ArrayList.

In der ersten Situation können Sie nicht synchronisieren, da Sie nur Objekte synchronisieren können (auf die durch Referenzvariablen verwiesen wird).

In der zweiten Situation hängt alles davon ab, worauf die lokale Variable verweist. Wenn es auf ein Objekt verweist, auf das auch andere Threads zeigen können (können), müssen Sie sicherstellen, dass der Code ordnungsgemäß synchronisiert ist.

Beispiele: Sie haben die lokale Variable aus einem static- oder Instanzfeld zugewiesen oder das Objekt aus einer gemeinsam genutzten Sammlung erhalten.

Wenn das Objekt jedoch in Ihrem Thread erstellt und nur dieser lokalen Variablen zugewiesen wurde und Sie niemals einen Verweis darauf von Ihrem Thread auf einen anderen Thread herausgeben und die Objektimplementierung selbst keine Referenzen ausgibt, dann Sie Sie brauchen sich nicht um die Synchronisation zu kümmern.

10
Erwin Bolwidt

Sie sprechen über den folgenden Fall:

public class MyClass {
    public void myMethod() {
        //Assume Customer is a Class
        Customer customer = getMyCustomer();
        synchronized(customer) {
            //only one thread at a time can access customer object
              which ever holds the lock
        }
    }
}

Im obigen Code istcustomer eine lokale Referenzvariable, Sie verwenden jedoch immer noch einen synchronisierten Block , um den Zugriff auf das Objekt zu beschränken, auf das customer zeigt ( von einem einzelnen Thread zu einem Zeitpunkt ).

Im Java-Speichermodell leben Objekte im Heap (obwohl Verweise lokal auf einem Thread liegen, der in einem Stack lebt). Bei der Synchronisierung wird der Zugriff auf ein Objekt auf dem Heap jeweils um genau einen Thread beschränkt . 

Kurz gesagt, wenn Sie lokale Variable (nicht primitiv) sagen, ist nur der Verweis lokal, nicht aber das eigentliche Objekt selbst, dh es bezieht sich tatsächlich auf ein Objekt auf dem Heap , auf das viele andere zugreifen können Fäden. Aus diesem Grund benötigen Sie eine Synchronisierung für das Objekt, damit ein einzelner Thread nur auf dieses Objekt gleichzeitig zugreifen kann.

12
developer

Der Punkt ist: Die Synchronisation erfolgt zu einem bestimmten Zweck. Sie verwenden es, um sicherzustellen, dass genau ein Thread zu einem bestimmten Zeitpunkt eine bestimmte schutzwürdige Aktivität ausführen kann. 

Also: wenn Sie eine Synchronisation benötigen, geht es immer um more als einen Thread. Und natürlich müssen Sie sich auf etwas beschränken, auf das alle diese Threads Zugriff haben.

Oder anders ausgedrückt: Es hat keinen Sinn, dass Sie die Tür verriegelt, um zu verhindern, dass Sie das Gebäude betritt. 

Aber, wie die andere Antwort zeigt, hängt es tatsächlich von der Definition der "lokalen" Variablen ab. Lass uns sagen, du hast:

void foo() {
  final Object lock = new Object();
  Thread a = new Thread() { uses lock
  Thread b = new Thread() { uses lock

dann sicher, dass die "lokale" Variable für diese beiden Threads als Sperre verwendet werden kann. Und darüber hinaus: Dieses Beispiel funktioniert, weil die Synchronisierung am Monitor eines bestimmten Objekts erfolgt. Und Objekte befinden sich auf dem Haufen. Alle von ihnen.

5
GhostCat

Ja, es ist sinnvoll, wenn die lokale Variable verwendet wird, um den Zugriff auf einen Codeblock von Threads zu synchronisieren, die in derselben Methode wie die lokale Variable definiert und erstellt werden.

2
Boris Pavlović