He pasado por un conjunto de sorpresas cuando se trata de la implementación de cola para un sistema de subprocesamiento múltiple. Aquí está: -Sincronizado vs ReentrantLock en el rendimiento
El escenario: - 1 productor, 1 consumidor: - Un productor pone un número entero en una cola. Un consumidor simplemente lo elimina de la cola.
La estructura de datos subyacente de la cola: - TreeSet (que nunca pensé que voy a utilizar), LinkedList, LinkedBlockingQueue (con un tamaño indefinido)
El código: - de TreeSet como una cola: -
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();
}
}
Para 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();
}
}
Para LinkedList: código similar con sincronizado.
las preguntas: -
1) Cuando he medido el rendimiento a través de Visual VM, he observado que la del código del productor, TreeSet se comporta mejor que LinkedBlockingQueue y LinkedList, a pesar de que toma O (log el tiempo n) , la creación de objetos en estructuras vinculadas es una sobrecarga significativa. ¿Por qué la teoría es bastante diferente de la práctica? ¿Por qué preferimos estructuras vinculadas y de matriz sobre estructuras de árbol en implementaciones de cola?
2) El sincronizado aparece como un ganador claro frente a ReeentrantLock porque TreeSet funcionó mejor que LinkedList, que tuvo un mejor rendimiento que LinkedBlockingQueue. Desearía poder adjuntar los resultados de Visual VM. No es en votos con el artículo, http://www.ibm.com/developerworks/java/library/j-jtp10264/index.html
Las operaciones se realizan en
Dell Vostro 1015, core 2 duo 2,10, 2 GB Ram con el sistema operativo de 32 bits y con
JVM: Java HotSpot (TM) VM cliente (20.1-b02, modo mixto) Java: la versión 1.6.0_26, proveedor de Sun Microsystems Inc.
Es casi el mismo ejemplo para el que adjunté un enlace en mi pregunta. Me dice que el rendimiento de REL es mejor que sincronizado comenzando con 2 hilos. También creo que si obtengo una manera de forzar al programador de sistema operativo a ejecutar los hilos en todas las CPU disponibles, definitivamente obtendremos un mejor rendimiento para LinkedBlockingQueues. Si necesita mis datos de observación, hágamelo saber. – 100pipers
Kumar olvidó mencionar que tomó su respuesta de [David Dice's Weblog] (https://blogs.oracle.com/dave/entry/java_util_concurrent_reentrantlock_vs). –
@AlexanderRyzhov gracias por dejarme señalar al autor original de este artículo, mientras lo leía mientras me estaba preparando para mi scjp de otro blog ... muchas gracias –