Wenn mehr als ein Thread ein Feld zugreifen kann, sollte es als flüchtiges gekennzeichnet sein?

StackOverflow https://stackoverflow.com/questions/1621495

  •  06-07-2019
  •  | 
  •  

Frage

ein paar Fäden Reading ( Schlüsselwort volatile Speichermodell ) ich bin verwirrt über Concurrency Probleme in Java.

Ich habe eine Menge von Feldern, die um mehr als einen Thread zugegriffen werden. Sollte ich durch sie gehen und markieren sie alle als flüchtig?

Beim Erstellen einer Klasse I nicht bewusst bin, ob mehrere Threads darauf zugreifen wird, so sicher ist es unsicher jedes Feld zu lassen nicht flüchtig sein, so von meinem Verständnis gibt es nur sehr wenige Fälle ist wouldn Sie ‚t verwenden. Ist das richtig?

Für mich ist spezifisch für die Version 1.5 JVMs und später, aber nicht beschränkt fühlt über meine spezifische Setup zu beantworten.

War es hilfreich?

Lösung

Wenn ein Feld von mehreren Threads zugegriffen wird, soll es mit synchronisierten Blöcken nur volatile oder final oder abgerufen werden. Andernfalls kann nicht zugewiesenen Werte zu anderen Threads sichtbar sein.

hat eine Klasse speziell für den gleichzeitigen Zugriff von mehreren Threads ausgelegt werden. Einfach Markierfeldern flüchtige oder endgültig ist für Thread-Sicherheit nicht ausreichend. Es gibt Konsistenzprobleme (Unteilbarkeit von Änderungen an mehrere Felder), Bedenken über inter-thread-Signalisierung (zum Beispiel unter Verwendung von wait und notify), etc.

Also, ist es am sichersten, anzunehmen, dass ein Objekt nur ein einzigen Thread sichtbar sein soll, es sei denn, es anders dokumentiert ist. Machen Sie alle Ihre Objekte Thread-sicher ist nicht erforderlich, und ist teuer in Bezug auf Software-Geschwindigkeit, aber noch wichtiger ist, in Bezug auf die Entwicklungskosten.

Stattdessen sollte Software so gestaltet werden, dass gleichzeitige Threads miteinander so wenig wie möglich in Wechselwirkung treten, vorzugsweise überhaupt nicht. Die Punkte, an denen sie müssen interagieren eindeutig identifiziert werden, so dass die richtige Gleichzeitigkeit Kontrollen ausgelegt werden können.

Andere Tipps

Nun, haben Sie die anderen Fragen gelesen und ich nehme an, Sie die Antworten bereits gelesen haben, so dass ich nur einige wichtige Punkte hervorheben:

  1. werden sie ändern? wenn nicht, müssen Sie nicht flüchtig benötigen
  2. Wenn ja, dann wird der Wert eines Feldes zu einem anderen Zusammenhang ist? wenn ja, gehen zu Punkt 4
  3. , wie viele Threads wird es ändern? wenn nur 1, dann flüchtig ist alles, was Sie benötigen
  4. , wenn die Antwort auf die Nummer 2 ist „nein“ oder mehr als ein Gewinde, um es schreiben wird, dann allein flüchtig ist nicht genug , müssen Sie wahrscheinlich den Zugang zu synchronisieren

Hinzugefügt:
Wenn das Feld ein Objekt verweisen, dann wird es hat Felder der eigenen und all jene Überlegung gilt auch für diese Felder aus.

Wenn Sie fragen müssen, verwenden Sie Schlösser. volatile kann in einigen Fällen nützlich sein, aber es ist sehr, sehr schwierig, richtig zu machen. Zum Beispiel:

class Foo {
  private volatile int counter = 0;
  int Increment() {
    counter++;
    return counter;
  }
}

Wenn zwei Threads Increment() zur gleichen Zeit laufen, ist es möglich, dass das Ergebnis counter = 1 werden. Dies ist, weil der Computer zuerst counter abrufen, fügen Sie ein, dann speichern zurück. Volatile zwingt nur die speichern und laden in einer bestimmten Reihenfolge im Vergleich zu anderen Aussagen kommen.

Beachten Sie, dass synchronized in der Regel die Notwendigkeit volatile vermeidet -., Wenn alle zu einem bestimmten Feld Zugriffe durch die gleichen Monitor geschützt sind, volatile wird nie benötigt werden,

volatile Verwendung zu lockless Algorithmen ist sehr, sehr schwierig zu machen; halten Sie sich an synchronized es sei denn, man harte Beweise haben, dass es bereits zu langsam ist, und haben auf dem Algorithmus Sie detaillierte Analyse durchgeführt Plan umzusetzen.

Die kurze Antwort ist nein. Threading Probleme erfordern mehr Überlegung und Planung als diese. Siehe diese für einige Einschränkungen auf, wenn flüchtige trägt dazu bei, Einfädeln und wenn dies nicht der Fall. Die Modifizierung der Werte hat richtig synchronisiert werden, aber typischerweise sehr Modifikation erfordert, die den Zustand von mehr als eine Variable zu einer Zeit. Nehmen wir zum Beispiel haben Sie Variable und Sie wollen es ändern, wenn es ein Kriterium erfüllt. Das Lesen aus dem Array und der Schreibvorgang in dem Array gibt verschiedene Befehle und müssen zusammen synchronisiert werden. Flüchtige ist nicht genug.

Betrachten wir auch den Fall, wo die Variable ein veränderliches Objekt verweist (zB ein Array oder eine Collection), dann mit dem Objekt interagiert nicht nur threadsicher sein, da die Referenz flüchtig ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top