Frage zu ternären Operator

Hallo Leute

Wie auch andere Sprachen kennt Java den ternären Operator (condition ? true : false). Grundsätzlich ist mir die Verwendung dieses Operators schon klar. Eben ist allerdings mit ein paar Kollegen eine Diskussion über diesen Operator entbrannt.

Das Problem hängt im Prinzip mit multithreading etc. zusammen.

gegeben sei der folgender code:

b = (a > 10) ? 1 : a ;

was alternativ ja auch als

if (a > 10) {
b = 1 ;
} else {
b = a ;
}

geschrieben werden kann. Erfolgt diese Zuweisung nun allerdings in einer Methode, die aus mehreren Threads aufgerufen werden kann und a ist ein Member, wäre es ja theoretisch möglich, dass zwischen dem Vergleich und der Zuweisung sich der Wert von a ändert.

(klar - dafür hat man synchronisierte Blöcke - ist aber nicht das Thema)

Streitpunkt bei unserer Diskussion war nun, ob sich die beiden Codeteile in einer multithreaded-Umgebung anders verhalten - sprich ob es im ersten Fall dazu kommen kann, dass sich zwischen Vergleich und Zuweisung der Wert von a ändern kann.

Ich habe jetzt einiges gesucht und lediglich herausgefunden, dass es definitif einen Unterschied macht, wenn ich mit volatile Variablen arbeite. Wenn ich es recht verstanden habe, sind Operationen auf volatile Variablen immer atomar, d.h. auch in multithreaded-Umgebungen würde das erste Statement NIE unterbrochen.

Ist das der einzige „echte“ Unterschied zwischen den beiden Konstrukten? Mir ist schon klar, dass es noch andere Unterschiede gibt da in manchen Fällen Operatoren erlaubt aber sonstige Konstrukte verboten sind (z.b. Variablenzuweisung gleichzeitig mit Deklaration), aber das meine ich hier nicht.

Grosse Zusatzpreisfrage: ich verwende den ternären Operator ausschließlich mit volatile-Variablen in einer multithreaded-Umgebung und im true-Zweig rufe ich eine Methode auf, die länger läuft:

a = (b > 10) ? f(b) : b ;

public static int f(int b) {
// lange dauernder code…
}

wenn ich das richtig sehe, störe ich damit ziemlich massiv den Scheduler beim arbeiten und meine schönen Threads kommen sich massiv in die Quere. Liege ich da richtig?

LG
Erwin

public static void main(String[] args) {
int a = 12;
int b = (a == 135) ? 1 : a;
}

ergibt folgenden Code:

public static void main(java.lang.String[]);
Code:
0: bipush 12
2: istore_1
3: iload_1
4: sipush 135
7: if_icmpne 14
10: iconst_1
11: goto 15
14: iload_1
15: istore_2
16: return
}

public static void main(String[] args) {
int a = 12;
int b;

if (a == 135) {
b = 1;
} else {
b = a;
}
}

ergibt folgenden Code:
public static void main(java.lang.String[]);
Code:
0: bipush 12
2: istore_1
3: iload_1
4: sipush 135
7: if_icmpne 15
10: iconst_1
11: istore_2
12: goto 17
15: iload_1
16: istore_2
17: return
}

Also im Prinzip gleich.

etwas technischer als erwartet aber ok

erwin

hab mir vorher deinen Artikel nicht ganz durchgelesen. sorry.

zu volatile:
laut Java language specification besagt volatile folgendes:
„A field may be declared volatile, in which case a thread must reconcile its working copy of the field with the master copy every time it accesses the variable. Moreover, operations on the master copies of one or more volatile variables on behalf of a thread are performed by the main memory in exactly the order that the thread requested.“
=> diese Operationen sind nicht atomar, sondern die Variable wird immer neu geladen um den aktuellen Wert zu verwenden. Bei den If-Statements macht das keinen Unterschied, da hier sowieso der Wert nicht zwischengespeichert wird.

a = (b > 10) ? f(b) : b ;
=> warum sollte hier der Scheduler gestört werden?

a = (b > 10) ? f(b) : b ;
=> warum sollte hier der Scheduler gestört werden?

aufgrund deiner erklärung natürlich gar nicht.

wie gesagt - interner disput mit ein paar kollegen und ich wollte mal ganz sicher gehen.

vielen dank für deine mühe

erwin