threads lock intrinsic java synchronization file-access

intrinsic - Cómo sincronizar el acceso al archivo en una carpeta compartida usando Java(O: ReadWriteLock en el nivel de la red)



synchronized java (4)

Puede usar las capacidades de bloqueo de NIO. Ver FileChannel # lock () .

Sin embargo, esto solo funcionará si el sistema de archivos subyacente admite el bloqueo a través de la red. Los NFS recientes deberían ser compatibles. Probablemente, Samba también los apoye, pero no puede decirlo con certeza.

Ver artículo por ejemplo.

Tengo varias aplicaciones ejecutándose en una máquina virtual. Tengo varias máquinas virtuales ejecutándose en un servidor. Y tengo varios servidores. Todos comparten un archivo usando una carpeta compartida en Linux. El archivo es leído y escrito por todas las aplicaciones. Durante el proceso de escritura, ninguna aplicación puede leer este archivo. Lo mismo para escribir: si una aplicación está leyendo el archivo, ninguna aplicación puede escribirlo.

¿Cómo puedo sincronizar las aplicaciones para que esperen a que finalice el proceso de escritura antes de leer, y viceversa? (las aplicaciones dentro de una vm deben estar sincronizadas y también aplicaciones en todos los servidores)

La implementación de Curent usa "semáforos de archivos". Si el archivo está a punto de escribirse, la aplicación intenta "adquirir" el semáforo creando un archivo adicional (asígnele el nombre "file.semaphore") en la carpeta compartida. Si el archivo "file.semaphore" ya existe, significa que el semáforo ya está bloqueado por una aplicación diferente. Este enfoque tiene el problema de que no puedo asegurarme de que el "archivo existe" - prueba y "crea archivo" - la operación se ejecuta atómica. De esta forma es posible que dos aplicaciones prueben el archivo "file.semaphore", vea que no existe e intente crear el archivo al mismo tiempo.


Eche un vistazo a los Javadocs para el método createNewFile () ; especifica específicamente que la creación de archivos no es un método confiable para la sincronización, y recomienda la clase FileLock en su lugar (es otro paquete en java.nio.channels por lo que es esencialmente lo mismo que Ivan Dubrov está sugiriendo).

Esto implicaría que su identificación del problema es precisa, y ninguna cantidad de juego resolverá esto con la creación tradicional de archivos. Mi primer pensamiento fue verificar el código de retorno de createNewFile (), pero si los Javadocs dicen que no es adecuado, es hora de seguir adelante.


Es necesario combinar el bloqueo de archivos para la protección entre las JVM con la sincronización dentro de los hilos de una JVM determinada. Vea la respuesta de cyber-monk aquí


También estoy tratando de determinar la mejor forma de resolver este problema para una situación similar (menos procesos participantes, pero el mismo problema subyacente). Si no ha podido emplear el esquema de bloqueo de archivos sugerido por Ivan (por ejemplo, el sistema | idioma | servicio de red no lo admite), tal vez podría designar a uno de los participantes como árbitro. Todos los participantes escriben semáforos únicos, llámalos "solicitud # .request" cuando quieren el archivo. El árbitro sondea el sistema de archivos para estos semáforos. Cuando ve uno, escribe "participante # .lock" y borra la solicitud. Si sucede que ve múltiples al mismo tiempo, selecciona uno al azar (o primero por tiempo de modificación del archivo) y borra solo su solicitud. Luego, el participante que emitió el bloqueo sabe que puede acceder al archivo de manera segura. Cuando el participante termina el archivo, elimina su propio bloqueo. Mientras haya un candado en su lugar, el árbitro no emitirá ningún otro candado. Cualquier solicitud que esté presente después de que el usuario elimine su bloqueo podría recibir un nuevo bloqueo sin emitir una nueva solicitud, por lo que los otros usuarios podrían sondear su bloqueo después de enviar la solicitud. Probablemente esto es lo que el mecanismo de bloqueo está haciendo de todos modos, excepto tal vez por la capacidad de administrar el bloqueo como una cola que viene con solicitudes procesadas en el orden en que se reciben (es decir, si el árbitro usa el tiempo de modificación). Además, como estás a cargo del árbitro, puedes establecer tiempos de espera en bloqueos, permitiéndole emitir semáforos de tiempo de espera al proceso que está acaparando el archivo y luego quitar el bloqueo (esperando, por supuesto, que si ese proceso con el bloqueo murió, lo hizo muy bien).