Hallo liebe Javagemeinde,
ich habe vor einiger Zeit mal einen Beitrag zum Thema "Lockfree"-Programming gesehen und versuche nun in meinem Projekt die Synchronisierung zu entfernen um mehr Durchsatz und von daher mehr Leistung zu erhalten, da Synchronisierung wohl "den Tod" bei
Multicores bedeutet. Bzw effektiv die Leistungssteigerung (z.B. durch einen Multicore) verhindert/verlangsamt.
Ich hoffe, dass es hier ein paar Experten zu diesem Thema gibt, da es meiner Meinung nach ein ziemlich komplexes Thema ist:
Ich habe einer Art Eventklasse, bei der man "Runnable"s registrieren kann, die bei Eintritt des Events benachrichtigt werden.
Ist das Event bereits eingetreten, soll diese "Registrierung" dafür sorgen, dass das Runnable SOFORT ausgeführt wird.
Mit synchronized kein Ding aber natürlich dickes Bottleneck, da ich diese Klasse SEHR OFT in meinem Projekt verwende!
Ich schreibe ein asynchrones Messaging-System, ähnlich JMS aber etwas abstrakter und besser einsetzbar.
Hier ist eine stark vereinfachte Version dieser Klasse:
Meine Fragen dazu:
A) Ist das hier eine korrekte Impl. um Thread-Safe zu garantieren ?
B) Sind die Bedingungen erfüllt ?
-Jedes Runnable darf/muss maximal einmal ausgeführt werden!
-finish() kann nur von maximal einem Thread auf true gesetzt werden! compareAndSet sollte dies verhindern!
-notifies(Runnable r) sollte eigentlich von beliebig vielen Threads parallel ausgeführt werden dürfen!
Die finale Frage ist aber : Lohnt sich hier der Stress ? Wäre ein simples synchronized besser/schneller ? Wohlgemerkt kann diese Klasse durchaus im großen Stil benutzt werden in meinem Fall! Also mehrere 100 Runnable könnten evt. in gewissen Abständen nacheinander mit notifies() hinzugefügt werden! Immer aus anderen Threads theoretisch...
So, ich hoffe ihr könnt mir da etwas helfen bzw Licht ins Dunkel bringen! Vlt. übertreibe ich ja auch und Synchroniserung ist garnicht so gravierend...
Die Infos, die ich habe, habe ich hierher:
JAX TV: Java-Programmierung im Multicore-Zeitalter
Gruß,
Chris
ich habe vor einiger Zeit mal einen Beitrag zum Thema "Lockfree"-Programming gesehen und versuche nun in meinem Projekt die Synchronisierung zu entfernen um mehr Durchsatz und von daher mehr Leistung zu erhalten, da Synchronisierung wohl "den Tod" bei
Multicores bedeutet. Bzw effektiv die Leistungssteigerung (z.B. durch einen Multicore) verhindert/verlangsamt.
Ich hoffe, dass es hier ein paar Experten zu diesem Thema gibt, da es meiner Meinung nach ein ziemlich komplexes Thema ist:
Ich habe einer Art Eventklasse, bei der man "Runnable"s registrieren kann, die bei Eintritt des Events benachrichtigt werden.
Ist das Event bereits eingetreten, soll diese "Registrierung" dafür sorgen, dass das Runnable SOFORT ausgeführt wird.
Mit synchronized kein Ding aber natürlich dickes Bottleneck, da ich diese Klasse SEHR OFT in meinem Projekt verwende!
Ich schreibe ein asynchrones Messaging-System, ähnlich JMS aber etwas abstrakter und besser einsetzbar.
Hier ist eine stark vereinfachte Version dieser Klasse:
Java:
package foxnet.system.util.concurrent.event;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
public class Event {
private final Queue<Runnable> queue = new ConcurrentLinkedQueue<Runnable>();
private final AtomicBoolean ab = new AtomicBoolean(false);
public void notifies(Runnable r) {
//Hole den aktuellen Wert
boolean state = ab.get();
//Wenn dieser Wert bereits true ist => run()
if (state) {
r.run();
return;
}
//Nun fügen wir hier erstmal r hinzu...
queue.offer(r);
//Nun überprüfen wir hier, ob AtomicBoolean false ist und erneut auf false gesetzt werden kann... CAS
if (!ab.compareAndSet(false, false)) {
//Wenn das nicht der Fall ist (Also eine Unterbrechung stattgefunden hat durch einen anderen Thread...)
if (queue.remove(r)) { //Versuche das Runnable zu entfernen
r.run(); //Sollte es funktioniert haben => run(), Wenn nicht, dann wurde das Runnable gerade eben noch ausgeführt!
}
}
}
public void finish() {
if (ab.compareAndSet(false, true)) { //Hier nur auf true setzen, wenn es noch nie auf true gesetzt wurde! AtomOp
Runnable r;
while ((r = queue.poll()) != null) {
r.run(); //Solange run() bis queue leer ist!
}
}
}
}
Meine Fragen dazu:
A) Ist das hier eine korrekte Impl. um Thread-Safe zu garantieren ?
B) Sind die Bedingungen erfüllt ?
-Jedes Runnable darf/muss maximal einmal ausgeführt werden!
-finish() kann nur von maximal einem Thread auf true gesetzt werden! compareAndSet sollte dies verhindern!
-notifies(Runnable r) sollte eigentlich von beliebig vielen Threads parallel ausgeführt werden dürfen!
Die finale Frage ist aber : Lohnt sich hier der Stress ? Wäre ein simples synchronized besser/schneller ? Wohlgemerkt kann diese Klasse durchaus im großen Stil benutzt werden in meinem Fall! Also mehrere 100 Runnable könnten evt. in gewissen Abständen nacheinander mit notifies() hinzugefügt werden! Immer aus anderen Threads theoretisch...
So, ich hoffe ihr könnt mir da etwas helfen bzw Licht ins Dunkel bringen! Vlt. übertreibe ich ja auch und Synchroniserung ist garnicht so gravierend...
Die Infos, die ich habe, habe ich hierher:
JAX TV: Java-Programmierung im Multicore-Zeitalter
Gruß,
Chris