¿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
synchronizedbloque. 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
synchronizedverá 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 unConditionpara 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=1no es un bloqueo de exclusión mutua.lockpor ejemplo,ReentrantLockunmutex? No estoy seguro de por quémutexybinary semaphorese están equiparando a la misma entidad.Semaphorepuede 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 Implementationfuente
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
Semaphoresea 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