Java Quiz

[SPOILER]Es gibt x == 0 aus. Dieses kann auch öfters vorkommen je nach dem, wie die Threads sich gegenseitig unterbrechen oder halt nur 1x.[/SPOILER]

+1

static != volatile, die threads können die statische variable jeweils für sich cachen

[QUOTE=Firephoenix]+1
[SPOILER]static != volatile, die threads können die statische variable jeweils für sich cachen[/SPOILER][/QUOTE]

[SPOILER]aber auch wenn die Variable volatile wäre, kann x == 0 mehrmals ausgegeben werden, da die Unterbrechung jederzeit passieren kann [/SPOILER]

Das erklärt nicht, wieso es bei n Threads genau ((n*2)-1)mal 0 ausgegeben wird. Und auch nicht, wieso der theoretisch mögliche Wert 1 (neben 0) nicht ausgegeben wird.

Weil ein Thread oder mehrere Threads doppelt durchlaufen, weil sie diese „1“ sehen und 1-1 => 0 is und sie somit nochmal durchlaufen. Das zumindest zu der ersten Frage von dir :slight_smile: … und das Zweite wird denke ich was mit „printf“ zu tun haben, das steht ja bestimmt nicht umsonst da …aber nachschauen wäre jetzt unfair :wink: ,… lasse mich da mal überraschen :wink:

Auflösung:
[spoiler]Mit printf hat das nichts zu tun. Vermutung: 3 Threads werden gestartet,: jeweils ein neuer, wenn die printf-Anweisung erreicht wurde. Auch arbeiten die 3 Threads mit lokalen Kopien der Variable x, die nicht immer unmittelbar aktualisiert werden müssen. Dadurch kann dann ein Wert 1 sein und 1-1=0 gerechnet werden, wodurch eine Schleife erneut durchlaufen werden würde.
Das sind nur meine Erklärungsversuche. Bitte nicht gleich Rübe ab.[/spoiler]

vlg, cb

Tatsächlich kann man garnichts dazu sagen was passiert.

Wenn man von static und volatile absieht sowie “x = 1 - x;” als atomare Operation ansieht.

Dann ergibt sich, dass die Anzahl der Ausgaben mindestens 1 und Ungerade sein muß.

Ungerade weil man das ganze auch wie folgt umschreiben könnte.

...
while(x) {
  x = !x;
}```

Wenn das Programm terminiert, dann muß der letzte Zustand von x == false sein.
Jeder Besuch des Schleifenrumpfs hat eine Zustandsänderung von x, sowie eine Ausgabe zur Folge.

Nimmt man nun eine größere Anzahl von Threads, dann können diese auch am Schleifenkopf scheitern.

Auch kommt nicht immer x == 0 heraus. Nimmt man eine größere Anzahl von Threads, dann sieht man, dass es durchaus vorkommt dass x == 1 ist.

Durch das volatile können Threads auch parallel x auf den gleichen Wert setzen, womit die Ungerade Anzahl an Ausgaben auch widerlegt würde.

Ich fands jedenfalls Interessant zu sehen, wie schnell man mit mehreren Threads, völlig wilkürliche Ergebnisse bekommt.

Auf jeden Fall recht interessanter Ansatz, um zufällige Binärzahlen zu erzeugen :smiley:

[QUOTE=Unregistered]Tatsächlich kann man garnichts dazu sagen was passiert.

Wenn man von static und volatile absieht sowie “x = 1 - x;” als atomare Operation ansieht.[/QUOTE]

Selbst wenn es keine atomare (subtraktions- und zuweisungs-) Operation ist (das wäre sie mit volatile auch nicht), kann x nur den Wert 0 oder 1 haben und als Ergebnis nur 1 oder 0 geschrieben werden; nur durch diese Anweisungszeile kann x keinen anderen Wert haben, selbst wenn x während des Lesevorgangs verändert werden würde. Alles andere ok.

Zufallszahlen vielleicht auch möglich mit “while(true){ x = 1 - x; Thread.sleep(20L); sout(x); }”.

Sooo mal wieder was einfaches :smiley:
Was passiert:

		Object[] array = new Long[5];
		array[0] = "Hello World";
	}```

Da hab ich falsch geraten
[spoiler]Nichts erst wenn man auf den Wert im Array zugreift fliegt eine Exception[/spoiler]

stimmt wohl nicht. ich bekomm eine von eclipse unerkannte array store exception.

War vielleicht schon, aber…

        double d0 = ???
        double d1 = ???
        
        Double D0 = d0;
        Double D1 = d1;
        
        boolean b0 = (d0 == d1);
        boolean b1 = D0.equals(D1);
        
        System.out.println(b0 == b1);

Was muss bei den ??? stehen, damit “false” ausgegeben wird?

Ja, das war schon in etwas anderer Form.
[spoiler]Double.NaN[/spoiler]

Wer den JavaSpecialists Newsletter abbonniert hat, kennt es schon. Für alle anderen:

import java.util.concurrent.atomic.*;
public class MagicMirror {
    private static final ThreadLocalRandom tlr =
            ThreadLocalRandom.current();
    public boolean amIPretty() {
        return tlr.nextBoolean();
    }
    public static void main(String... args) {
        final AtomicBoolean vanity = new AtomicBoolean(true);
        while (vanity.get()) {
            new Thread(new Runnable() {
                public void run() {
                    MagicMirror mirrorOnTheWall = new MagicMirror();
                    boolean beauty = mirrorOnTheWall.amIPretty();
                    if (!beauty) vanity.set(false);
                }
            }).start();
        }
        System.out.println("Oh no, now I am depressed!");
    }
}```

Was passiert unter Java 7, was unter Java 8?

Im anderen Forum hatte ich schonmal die Frage gestellt, warum eine Enum nicht das Map-Interface implementieren kann. Wer Lust hat, kann darüber nochmal nachdenken und etwas dazu schreiben. Heute aber eine etwas andere Frage: Warum kann man mit einer Enum die Interfaces java.util.Set/java.util.List nicht korrekt implementieren (und sollte es darum auch nicht)?

[QUOTE=cmrudolph]Ja, das war schon in etwas anderer Form.
[spoiler]Double.NaN[/spoiler]
[/QUOTE]

OK, das hätte ich wohl explizit ausschließen sollen. Was muss dort stehen, wenn es NICHT „NaN“ sein darf? :smiley:

double d0 = 0.0;
double d1 = -0.0;

Antwort an Marco13
[SPOILER]0.0 und -0.0[/SPOILER]

Jupp, … so viele Möglichkeiten gäb’s dann ja auch nicht mehr.

Oder?

Was müßte dort stehen, um false zu erhalten, wenn man weder 0.0/-0.0 NOCH Double.NaN hinschreiben dürfte?

*** Edit ***

Spontan würde mir da höchstens sowas einfallen wie dass z.B. „hashCode“/„equals“ nicht entsprechend der contracts implementiert werden kann - meintest du das?

So langsam wirds rätselhaft :wink:

hashCode und equals muss man ja nicht implementieren. Die Standardimplementierung in Object erfüllt den Contract und auch die Listenimplementierungen im Java API überscheiben sie nicht.
Mir fällt auch kein sinnvoller Grund ein, weshalb man hashCode und equals bei Collections überschreiben sollte.