Ich habe einige Überraschungen erlebt, wenn es um die Queue-Implementierung für ein Multithreading-System geht. Hier ist: -Synchronisiert vs ReentrantLock auf Leistung
Das Szenario: - 1 Produzent, 1 Verbraucher: - Ein Produzent legt eine ganze Zahl in eine Warteschlange. Ein Verbraucher entfernt ihn einfach aus der Warteschlange.
Die zugrundeliegende Datenstruktur der Warteschlange: - TreeSet (was ich hätte nie gedacht, werde ich verwenden), LinkedList, LinkedBlockingQueue (mit unbestimmter Größe)
der Code: - von TreeSet als Warteschlange: -
while (i < 2000000) {
synchronized (objQueue) {
if (!(objQueue.size() > 0)) {
try {
objQueue.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Integer x = objQueue.first();
if (x != null) {
objQueue.remove(x);
++i;
}
}
}
EDIT: -
while (i < 2000000) {
synchronized (objQueue) {
objQueue.add(i);
++i;
objQueue.notify();
}
}
Für LinkedBlockingQueue: -
while (i < 2000000){
try {
objQueue.put(i);
++i;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Thread.currentThread().interrupt();
}
}
while (i < 2000000) {
try {
objQueue.take();
++i;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Thread.currentThread().interrupt();
}
}
Für LinkedList: - ähnlicher Code mit synchronisiert.
Die Fragen: -
1) Wenn ich die Leistung über Visuelle VM gemessen, ich festgestellt, dass die für den Erzeugercode, führt TreeSet besser als LinkedBlockingQueue und LinkedList, auch wenn es O (log n) Zeit in Anspruch nimmt Die Erstellung von Objekten in verknüpften Strukturen ist ein erheblicher Aufwand. Warum unterscheidet sich die Theorie von der Praxis? Warum bevorzugen wir Linked, Array-Strukturen gegenüber Tree-Strukturen in Warteschlangenimplementierungen?
2) Das synchronisierte kommt als eindeutiger Gewinner gegenüber dem ReeentrantLock heraus, da TreeSet besser als LinkedList war und eine bessere Performance als LinkedBlockingQueue aufwies. Ich wünschte, ich könnte die Visual VM-Ergebnisse anhängen. Es ist nicht in Stimmen mit dem Artikel, http://www.ibm.com/developerworks/java/library/j-jtp10264/index.html
Die Operationen auf
Dell Vostro 1015 durchgeführt werden, Core 2 Duo 2.10, 2 GB Ram mit 32-Bit-Betriebssystem und mit
JVM: Java HotSpot (TM) Client VM (20,1-b02, mixed mode) Java: Version 1.6.0_26, Anbieter Sun Microsystems Inc.
Es ist fast das gleiche Beispiel, für das ich einen Link in meiner Frage anschloss. Es sagt mir, dass die Leistung von REL besser als synchronisiert ist, beginnend mit 2 Threads. Außerdem habe ich das Gefühl, wenn wir einen Weg finden, den OS-Scheduler zu zwingen, die Threads auf allen verfügbaren CPUs auszuführen, werden wir definitiv eine bessere Leistung für LinkedBlockingQueues bekommen. Wenn Sie meine Beobachtungsdaten benötigen, lassen Sie es mich wissen. – 100pipers
Kumar vergaß zu erwähnen, dass er seine Antwort aus [David Dices Weblog] (https://blogs.oracle.com/dave/entry/java_util_concurrent_reentrantlock_vs) nahm. –
@AlexanderRyzhov danke für den Hinweis auf den ursprünglichen Autor dieses Artikels, wie ich dies las, während ich für meine scjp von so anderen Blog vorbereitete ... Vielen Dank –