Der folgende Code druckt manchmal "valueWrapper.isZero()" auf meinem Windows-PC und einem Mac, , die beide ihre JVM im Servermodus ausführen. Ok dies geschieht, weil der Wert Feld nicht endgültig in der ValueWrapper Klasse, so seine möglichen, daß einiger Thread dem abgestandenen Wert 0.Semantik der lokalen endgültigen Variable im Java Memory Model?
public class ConcurrencyApp {
private final Random rand = new Random(System.currentTimeMillis());
private ValueWrapper valueWrapper;
private static class ValueWrapper {
private int value;
public ValueWrapper(int value) {
this.value = value;
}
public boolean isZero() {
return value == 0;
}
}
private void go() {
while (true) {
valueWrapper = new ValueWrapper(randomInt(10, 1024));
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
if (valueWrapper.isZero()) {
System.out.println("valueWrapper.isZero()");
}
}
});
thread.start();
}
}
private int randomInt(int min, int max) {
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
public static void printVMInfos() {
String vmName = System.getProperty("java.vm.name");
System.out.println("vm name: " + vmName);
int cores = Runtime.getRuntime().availableProcessors();
System.out.println("available cores: " + cores);
}
public static void main(String[] args) {
ConcurrencyApp app = new ConcurrencyApp();
printVMInfos();
app.go();
}
}
Aber was ist mit der folgenden Modifikation sieht, hier habe ich eine lokale Finale Variable:
private void go() {
while (true) {
final ValueWrapper valueWrapper = new ValueWrapper(randomInt(10, 1024));
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
if (valueWrapper.isZero()) {
System.out.println("valueWrapper.isZero()");
}
}
});
thread.start();
}
}
Es sieht so aus, dass jetzt kein Thread einen schalen Wert von 0. sieht aber ist dies durch die JMM garantiert? Ein kurzer Blick in die Spezifikation überzeugt mich nicht.
Sind Sie sicher, dass das erste Code-Snippet ohne Endung in der Zeile vor dem Thread ausgeführt wird? –
@DhanaKrishnasamy: Es wird ausgeführt, da ValueWrapper ein Feld der ConcurrencyApp ist – user2867869