2010-05-24 17 views
15

En Java, do ReentrantLock.lock() y ReetrantLock.unlock() utilizan el mismo mecanismo de bloqueo que synchronized()?Mezcla sincronizada() con ReentrantLock.lock()

Mi conjetura es "No", pero espero estar equivocado.

Ejemplo:

Imagínese que el hilo 1 y Tema 2 ambos tienen acceso a:

ReentrantLock lock = new ReentrantLock(); 

hilo 1 se ejecuta:

synchronized (lock) { 
    // blah 
} 

de rosca 2 se ejecuta:

lock.lock(); 
try { 
    // blah 
} 
finally { 
    lock.unlock(); 
} 

Supongamos que el hilo 1 llega es la primera parte, luego el Subproceso 2 antes de que finalice el Subproceso 1: ¿subirá el Subproceso 2 al Subproceso 1 para salir del bloque synchronized() o se ejecutará?

Respuesta

14

No, subproceso 2 puede lock() incluso cuando el subproceso 1 es synchronized en el mismo lock. Esto es lo que el documentation tiene que decir:

Tenga en cuenta que los casos de bloqueo son sólo objetos normales y pueden ser ellos mismos usado como objetivo en un comunicado sincronizada. La adquisición de la cerradura del monitor de una instancia de Lock no tiene relación especificada con la invocación de cualquiera de la cerradura () de esa instancia. Se Se recomienda que para evitar confusiones nunca utiliza casos de bloqueo de esta manera , excepto dentro de su propio aplicación.

+0

Eso es lo que pensé. Hay un lugar donde necesito usar 'ReetrantLock.tryLock()', y esperaba salirse con 'synchronized' en todos lados. Gracias. –

9

Los dos mecanismos son diferentes. Implementación/rendimiento:

  • el mecanismo sincronizado utiliza un mecanismo de bloqueo que está "integrado" en la JVM; el mecanismo subyacente está sujeto a la implementación de JVM particular, pero típicamente usa una combinación de una instrucción compare-and-set operation (CAS) sin formato para los casos en que no se contenta el bloqueo más los mecanismos de bloqueo subyacentes provistos por el sistema operativo;
  • las clases de bloqueo como ReentrantLock son, básicamente, codificados en Java puro (a través de una biblioteca introducido en Java 5, que expone las instrucciones del CAS y descheduling hilo de Java) y por lo tanto es un poco más estandarizada a través del sistema operativo de y más controlable (véase más adelante).

En algunas circunstancias, los bloqueos explícitos pueden tener un mejor rendimiento. Si nos fijamos en este comparison of locking mechanisms He realizado bajo Java 5, se verá que en esa prueba en particular (múltiples hilos de acceso una matriz), las clases de bloqueo explícito configurados en modo "injusto" (los triángulos de color amarillo y cian) permiten un mayor rendimiento que sencilla sincronizado (las flechas moradas).

(También debo decir que el rendimiento del sincronizado se ha mejorado en las versiones más recientes de Hotspot, puede que no haya mucho en las últimas versiones o incluso en otras circunstancias-- esto es obviamente una prueba en un entorno .)

funcionalidad en cuanto a:

  • el mecanismo sincronizado proporciona una funcionalidad mínima (se puede bloquear y desbloquear, de bloqueo es una operación de todo o nada, es más sujeto al algoritmo de los autores decidieron utilizar encendido), aunque con la ventaja de la sintaxis incorporada y algunos controles integrados en la JVM;
  • las clases bloqueo explícito proporcionan un mayor control, en particular, se puede especificar una cerradura "justo", con un tiempo de espera de bloqueo, sustituir si es necesario alterar behiour de la cerradura ...
0

¿Por qué hizo el balance estático en la clase de Cuenta? Elimina la estática y debería funcionar.

Además, tiene una pregunta sobre el uso de su hilo. En su TestMain, usted crea nuevos hilos y asigna los ejecutables como WithdrawRequests & DepositRequests. Pero nuevamente crea hilos nuevos dentro de los constructores de esos ejecutables. ¡Esto hará que el método de ejecución se ejecute dos veces!