¿Hay un objeto Mutex en Java o una forma de crear uno? Lo pregunto porque un objeto Semaphore inicializado con 1 permiso no me ayuda. Piense en este caso:
try {
semaphore.acquire();
//do stuff
semaphore.release();
} catch (Exception e) {
semaphore.release();
}
si ocurre una excepción en la primera adquisición, la liberación en el bloque de captura aumentará los permisos y el semáforo ya no es un semáforo binario.
¿Será la forma correcta?
try {
semaphore.acquire();
//do stuff
} catch (Exception e) {
//exception stuff
} finally {
semaphore.release();
}
¿El código anterior asegurará que el semáforo sea binario?
Respuestas:
Consulte esta página: http://www.oracle.com/technetwork/articles/javase/index-140767.html
Tiene un patrón ligeramente diferente que es (creo) lo que estás buscando:
En este uso, solo está llamando
release()
después de una exitosaacquire()
fuente
Cualquier objeto en Java se puede utilizar como bloqueo mediante un
synchronized
bloque. Esto también se encargará automáticamente de liberar el bloqueo cuando ocurra una excepción.Puede leer más sobre esto aquí: Bloqueos intrínsecos y sincronización
fuente
synchronized
verá qué es mejor legible y menos propenso a errores.transaction.begin(); transaction.commit()
. Ej .).someObject.wait(timeout)
ysomeObject.notify()
mientras mira el código de esta respuesta.fuente
"Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements."
, de: docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/… ... aunque tienes razón. La respuesta de Argv no ilustra ni explica estas operaciones.private final ReentrantLock _mutex = ...
, puede usar getHoldCount () para devolver el número de re-bloqueos de subprocesos. (Puede aplicar unCondition
para evitar esto. Consulte la API ).Nadie ha mencionado esto claramente, pero este tipo de patrón generalmente no es adecuado para semáforos. La razón es que cualquier hilo puede liberar un semáforo, pero normalmente solo desea que el hilo propietario que originalmente se bloqueó pueda desbloquearse . Para este caso de uso, en Java, usualmente usamos ReentrantLocks, que se puede crear así:
Y el patrón de diseño habitual de uso es:
Aquí hay un ejemplo en el código fuente de Java donde puede ver este patrón en acción.
Las cerraduras reentrantes tienen el beneficio adicional de apoyar la equidad.
Use semáforos solo si necesita una semántica que no sea de liberación de propiedad.
fuente
count=1
no es un bloqueo de exclusión mutua.lock
por ejemplo,ReentrantLock
unmutex
? No estoy seguro de por quémutex
ybinary semaphore
se están equiparando a la misma entidad.Semaphore
puede ser liberado por cualquier hilo, por lo que puede no garantizar la proteccióncritical section
. ¿Alguna idea?Creo que deberías probar con:
Durante la inicialización del semáforo:
Y en tu
Runnable Implementation
fuente
El error en la publicación original es el conjunto de llamadas adquisiciones () dentro del bucle try. Aquí hay un enfoque correcto para usar un semáforo "binario" (Mutex):
fuente
Para asegurarse de que a
Semaphore
sea binario, solo debe asegurarse de pasar el número de permisos como 1 al crear el semáforo. Los Javadocs tienen un poco más de explicación.fuente
El bloqueo de cada objeto es un poco diferente del diseño Mutex / Semaphore. Por ejemplo, no hay forma de implementar correctamente el desplazamiento de nodos vinculados liberando el bloqueo del nodo anterior y capturando el siguiente. Pero con mutex es fácil de implementar:
Actualmente, no existe tal clase en
java.util.concurrent
, pero puede encontrar la implementación de Mutext aquí Mutex.java . En cuanto a las bibliotecas estándar, Semaphore proporciona toda esta funcionalidad y mucho más.fuente