Die Frage wurde bereits hier gestellt, aber es wurde kein richtiges Beispiel bereitgestellt, das funktioniert. Also erwähnt Brian, dass unter bestimmten Bedingungen der AssertionError im folgenden Code auftreten kann:
public class Holder {
private int n;
public Holder(int n) { this.n = n; }
public void assertSanity() {
if (n!=n)
throw new AssertionError("Diese Aussage ist falsch");
}
}
Wenn Holder wie folgt falsch veröffentlicht wird:
Klasse SomeClass {
public Holder holder;
public void initialize() {
holder = new Holder(42);
}
}
Ich verstehe, dass dies geschehen würde, wenn die Referenz auf Holder sichtbar gemacht wird, bevor die Instanzvariable des Objekts Holder für einen anderen Thread sichtbar gemacht wird. Daher habe ich das folgende Beispiel erstellt, um dieses Verhalten zu provozieren und somit den AssertionError mit folgender Klasse:
public class Publish {
public Holder holder;
public void initialize() {
holder = new Holder(42);
}
public static void main(String[] args) {
Publish publish = new Publish();
Thread t1 = new Thread(new Runnable() {
public void run() {
for(int i = 0; i < Integer.MAX_VALUE; i++) {
publish.initialize();
}
System.out.println("Initialisierungsthread beendet");
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
int nullPointerHits = 0;
int assertionErrors = 0;
while(t1.isAlive()) {
try {
publish.holder.assertSanity();
} catch(NullPointerException exc) {
nullPointerHits++;
} catch(AssertionError err) {
assertionErrors ++;
}
}
System.out.println("Nullpointer-Treffer: " + nullPointerHits);
System.out.println("Assertion-Fehler: " + assertionErrors);
}
});
t1.start();
t2.start();
}
}
Unabhängig davon, wie oft ich den Code ausführe, tritt der AssertionError nie auf. Für mich gibt es also mehrere Optionen:
- Die JVM-Implementierung (in meinem Fall Oracle's 1.8.0.20) setzt durch, dass die Invarianten, die während der Konstruktion eines Objekts festgelegt wurden, für alle Threads sichtbar sind.
- Das Buch ist falsch, was ich bezweifeln würde, da der Autor Brian Goetz ist ... nuf sagte
- Ich mache etwas falsch in meinem obigen Code
Also die Fragen die ich habe: - Hat jemand jemals erfolgreich diesen Art von AssertionError provoziert? Mit welchem Code dann? - Warum provoziert mein Code den AssertionError nicht?