Garantien für die Sichtbarkeit flüchtiger Variablen in JavaJava

Java-Forum
Guest
 Garantien für die Sichtbarkeit flüchtiger Variablen in Java

Post by Guest »

Ich habe mir einige Beiträge über flüchtige Variablen in Java angesehen. Aber ich bin immer noch etwas verwirrt, ganz zu schweigen davon, dass sich einige davon widersprechen.
Hier ist ein Beispiel, zu dem ich gerne eine Frage stellen würde:

Code: Select all

public class Main {

static  ArrayList list = new ArrayList();
static volatile int listSize = 0;

public static void main(String[] args) {
Thread writer = new Thread(Main::write);
Thread reader = new Thread(Main::read);
writer.start();
reader.start();
}

public static void write() {
while (true) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
return;
}
list.add(1);
listSize++;
System.out.println("Added an element.");

}
}

public static void read() {
int currentIndex = 0;
while (true) {
if(currentIndex>=listSize) {
continue;
}
System.out.println("Read an element.");
int element = list.get(currentIndex);
currentIndex++;
// do stuff with element...
}
}
}
In diesem Beispiel schreibt also ein Writer-Thread in eine ArrayList und ein Reader-Thread liest die Elemente aus dieser Liste. Laut einigen Antworten zu diesem Thema gäbe es, selbst wenn ich die Liste selbst flüchtig machen würde, keine Sichtbarkeitsgarantien zwischen Threads für den Inhalt der Liste, sondern nur für das Listenobjekt selbst . Mit anderen Worten, wenn der Writer-Thread dies tun würde:

Code: Select all

list = new ArrayList();
Der Leserthread wüsste davon. Aber wenn der Autoren-Thread die Liste hinzufügt/entfernt/ändert, wie im Beispiel oben, gibt es keine Garantie dafür, dass der Leser-Thread sie jemals sieht.
Und hier ist ein Zitat von a Buch mit dem Titel Java Concurrency in Practice von Brian Goetz et al.

Die Sichtbarkeitseffekte flüchtiger Variablen gehen über den Wert der flüchtigen Variablen hinaus Variable selbst. Wenn Thread A in eine flüchtige Variable schreibt und Thread B anschließend dieselbe Variable liest, werden die Werte aller Variablen, die für A vor dem Schreiben in die flüchtige Variable sichtbar waren, nach dem Lesen der flüchtigen Variablen für B sichtbar. Aus Sicht der Speichersichtbarkeit ist das Schreiben einer flüchtigen Variablen also wie das Verlassen eines synchronisierten Blocks und das Lesen einer flüchtigen Variablen wie das Betreten eines synchronisierten Blocks.

Dieses Zitat Dies ist auch der Grund, warum ich einen flüchtigen int erstellt habe, den der Writer-Thread jedes Mal erhöht, wenn er in die Liste schreibt, anstatt die Liste selbst flüchtig zu machen.
Deshalb habe ich dieses Beispiel mit und ohne die Variable volatile (anstelle von currentIndex) getestet >= listSize mit currentIndex >= list.size() ) und ohne die flüchtige Variable blockiert der Reader-Thread vollständig und sieht die hinzugefügten Elemente der Liste nie wirklich. Mit der flüchtigen Variablen sieht der Leser-Thread jedoch sofort die Änderung an der Liste. Anscheinend ist das Zitat aus dem Buch korrekt, aber ich möchte sicher sein, da das Beispiel, das ich geschrieben habe, auf etwas anderem basiert, das ich schreibe, und es nicht toll wäre, wenn der Leser-Thread auf unbestimmte Zeit blockiert.

Bearbeiten: Der Thread-Spin dient dazu, eine bessere Chance beim Caching zu erhalten.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post