geforkt von Mirrors/Velocity
Improve native initialization logic
This uses the double-check pattern as recommended in Effective Java.
Dieser Commit ist enthalten in:
Ursprung
9c05203ce8
Commit
e75ec71b32
@ -8,7 +8,7 @@ import java.util.function.Supplier;
|
|||||||
|
|
||||||
public class NativeCodeLoader<T> implements Supplier<T> {
|
public class NativeCodeLoader<T> implements Supplier<T> {
|
||||||
private final List<Variant<T>> variants;
|
private final List<Variant<T>> variants;
|
||||||
private Variant<T> selected;
|
private volatile Variant<T> selected;
|
||||||
|
|
||||||
public NativeCodeLoader(List<Variant<T>> variants) {
|
public NativeCodeLoader(List<Variant<T>> variants) {
|
||||||
this.variants = ImmutableList.copyOf(variants);
|
this.variants = ImmutableList.copyOf(variants);
|
||||||
@ -17,25 +17,32 @@ public class NativeCodeLoader<T> implements Supplier<T> {
|
|||||||
@Override
|
@Override
|
||||||
public T get() {
|
public T get() {
|
||||||
if (selected == null) {
|
if (selected == null) {
|
||||||
selected = select();
|
selected = tryLoad();
|
||||||
}
|
}
|
||||||
return selected.object;
|
return selected.object;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Variant<T> select() {
|
private Variant<T> tryLoad() {
|
||||||
|
synchronized (this) {
|
||||||
|
if (selected != null) {
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
|
||||||
for (Variant<T> variant : variants) {
|
for (Variant<T> variant : variants) {
|
||||||
T got = variant.get();
|
T got = variant.get();
|
||||||
if (got == null) {
|
if (got == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return variant;
|
selected = variant;
|
||||||
|
return selected;
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("Can't find any suitable variants");
|
throw new IllegalArgumentException("Can't find any suitable variants");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getLoadedVariant() {
|
public String getLoadedVariant() {
|
||||||
if (selected == null) {
|
if (selected == null) {
|
||||||
selected = select();
|
selected = tryLoad();
|
||||||
}
|
}
|
||||||
return selected.name;
|
return selected.name;
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren