by Anonymous » 17 Feb 2025, 04:22
Ich bin neu in sperrenfreien Algorithmen und versuche, Stack zu implementieren, was die einfachste lock-freie Datenstruktur ist. Hier ist meine Implementierung des begrenzten Array-basierten lock-freien Stacks. < /P>
Code: Select all
public class ConcurrentArrayStack implements Stack {
private final AtomicInteger size;
private final T array[];
public ConcurrentArrayStack(int maxCapacity) {
this.array = (T[]) new Object[maxCapacity];
this.size = new AtomicInteger(0);
}
@Override
public T push(T t) {
if(t == null) {
throw new NullPointerException("Null values are not allowed");
}
int currentSize;
T currentValue;
do {
currentSize = size.get();
if(currentSize == array.length) {
return null;
}
currentValue = array[currentSize];
} while(currentValue != null || !size.compareAndSet(currentSize, currentSize + 1));
array[currentSize] = t;
VarHandle.fullFence(); // am Ende jeder Methode lautet: < /p>
[*] Eine Compiler-Barriere (spülen Sie alle ausstehenden Lese-/Schreiben auf einem Compiler-Level)
[*] Flush Store-Buffer (x86), um zu vermeiden, dass abgestandene Daten aus einem anderen Kern gelesen werden.
Wir brauchen keinen Zaun zwischen der Last von Array und Speichern zu Array, da Ladungen nicht in frühere Speicherlager angeordnet sind (x86). < /li>
< /ol>
Frage: Das Ding ist, dass ich nicht überprüfen konnte, dass Fullfence
hier streng genommen erforderlich ist und nicht durch Erwerb - ersetzt werden kann
. Ist so etwas möglich?
Ich bin neu in sperrenfreien Algorithmen und versuche, Stack zu implementieren, was die einfachste lock-freie Datenstruktur ist. Hier ist meine Implementierung des begrenzten Array-basierten lock-freien Stacks. < /P>
[code]public class ConcurrentArrayStack implements Stack {
private final AtomicInteger size;
private final T array[];
public ConcurrentArrayStack(int maxCapacity) {
this.array = (T[]) new Object[maxCapacity];
this.size = new AtomicInteger(0);
}
@Override
public T push(T t) {
if(t == null) {
throw new NullPointerException("Null values are not allowed");
}
int currentSize;
T currentValue;
do {
currentSize = size.get();
if(currentSize == array.length) {
return null;
}
currentValue = array[currentSize];
} while(currentValue != null || !size.compareAndSet(currentSize, currentSize + 1));
array[currentSize] = t;
VarHandle.fullFence(); // am Ende jeder Methode lautet: < /p>
[*] Eine Compiler-Barriere (spülen Sie alle ausstehenden Lese-/Schreiben auf einem Compiler-Level)
[*] Flush Store-Buffer (x86), um zu vermeiden, dass abgestandene Daten aus einem anderen Kern gelesen werden.
Wir brauchen keinen Zaun zwischen der Last von Array und Speichern zu Array, da Ladungen nicht in frühere Speicherlager angeordnet sind (x86). < /li>
< /ol>
Frage: Das Ding ist, dass ich nicht überprüfen konnte, dass Fullfence [/code] hier streng genommen erforderlich ist und nicht durch Erwerb - ersetzt werden kann[code]release[/code]. Ist so etwas möglich?