2012-02-27 12 views
5

Estoy pensando aquí: si tiene 2 subprocesos ejecutando operaciones FAST que deben sincronizarse, ¿no es un enfoque no bloqueante más rápido/mejor que un enfoque de bloqueo/cambio de contexto?Cerraduras de bloqueo frente a cerraduras sin bloqueo

Por no bloqueante quiero decir algo como:

while (true) { si (checkAndGetTheLock)() break; }

Lo único que se me ocurre es la inanición (con la CPU quemada) si tiene demasiados hilos dando vueltas alrededor de la cerradura.

¿Cómo puedo equilibrar un enfoque con el otro?

+0

¿Cuántas operaciones de bloqueo va a hacer por núcleo de CPU por segundo? – usr

+0

AFAIK, la JVM hace esta optimización por usted si no hay contención en el bloqueo (que debería ser el caso si la operación es rápida) –

+0

@JB Nizet: Creo que tiene que tomar esa decisión usted mismo mediante el uso de ReentrantLock sincronizado. – chrisapotek

Respuesta

5

Esto es lo Java concurrencia en la práctica dice sobre el tema:

La JVM puede aplicar el bloqueo, ya sea a través de spin-espera (en repetidas ocasiones tratando de adquirir el bloqueo hasta que tenga éxito) o bysuspending la bloqueado hilo a través del sistema operativo. Cuál es más eficiente depende de la relación entre la sobrecarga del interruptor de contexto y el tiempo hasta que la cerradura esté disponible; la espera en espera es preferible para y la suspensión es preferible para largas esperas. Algunas JVM eligen entre las dos basadas en adaptaciones basadas en los datos de perfiles de espera anterior veces, pero la mayoría simplemente suspende subprocesos a la espera de un bloqueo.

Y también (que es, en mi opinión, el punto más importante):

No se preocupe excesivamente por el costo de la sincronización uncontended. El mecanismo básico ya es bastante rápido, y las JVM pueden realizar optimizaciones adicionales que reducen aún más o eliminan el costo. En su lugar, enfoca los esfuerzos de optimización en las áreas donde se produce la contención de bloqueo .

+0

No me gustaría confiar en que "Algunas JVM eligen entre las dos de forma adaptativa según los datos de perfil de los tiempos de espera pasados, pero la mayoría simplemente suspende los hilos que esperan un bloqueo". Pero nunca se puede saber de qué son capaces las modernas JVM de hotspot. Yo pensaría que sincronizado está bloqueando y ReentrantLock está ocupado esperando. Pero si pueden cambiarse el uno al otro en tiempo de ejecución, no estoy seguro. – chrisapotek

+1

¿Dónde ha leído que ReentrantLock está ocupado, esperando? Si lo hiciera, pondría a la JVM de rodillas por largas esperas. El javadoc dice: * Una exclusión mutua reentrante Bloquee con el mismo comportamiento básico y semántica que el bloqueo implícito del monitor al que se accede utilizando métodos y declaraciones sincronizados, pero con capacidades extendidas. * –

+0

Puedo estar equivocado, pero al navegar el código fuente pensé que era su enfoque: http://fuseyism.com/classpath/doc/java/util/concurrent/locks/AbstractQueuedSynchronizer-source.html ¡NOOOOO! La JVM NO usa ReentrantLock para sus funciones internas. – chrisapotek

1

Bueno, la única manera de estar seguro es probarlo. Cuando se trata de multihilo y rendimiento, simplemente no se puede asumir.

+0

Esta respuesta es correcta y no debe ser downvoted. – usr

+0

@usr, ¿por qué no lo votaste entonces? Estuve muy tentado de rechazarlo dos veces, pero eso sería injusto en M Platvoet. –

+0

Lo he subido. Hay un voto negativo de cancelación. – usr