java - proteger - como poner contraseña a una carpeta en el celular samsung
¿Cómo bloquear un archivo en diferentes niveles de aplicación? (6)
¿Sería capaz de emplear el uso de Semaphore para controlar el acceso como uno a la vez dentro de la aplicación?
Para citar la API "Los semáforos a menudo se usan para restringir el número de subprocesos que pueden acceder a algunos recursos (físicos o lógicos)"
Si bien esa API podría seguir siendo un contenedor específico, el concepto de un semáforo distribuido debería ser posible, posiblemente con JGroups .
Una búsqueda superficial en Google para ''semáforo de Java distribuido'' apareció Jukebox que parece que podría abordar el anterior
Aquí está el escenario: Tengo una aplicación web java de múltiples hilos que se ejecuta dentro de un contenedor de servlets. La aplicación se implementa varias veces dentro del contenedor de servlets. Hay varios contenedores de servlets ejecutándose en diferentes servidores.
Quizás este gráfico lo aclare:
server1
+- servlet container
+- application1
| +- thread1
| +- thread2
+- application2
+- thread1
+- thread2
server2
+- servlet container
+- application1
| +- thread1
| +- thread2
+- application2
+- thread1
+- thread2
Hay un archivo dentro de un directorio compartido de red al que todos esos hilos pueden acceder. Y acceden al archivo con frecuencia. La mayoría de las veces, el archivo solo es leído por esos hilos. Pero a veces está escrito.
Necesito una solución a prueba de fallas para sincronizar todos los hilos para garantizar la coherencia de los datos.
Soluciones que no funcionan (adecuadamente) :
Usando java.nio.channels.FileLock
Puedo sincronizar hilos de diferentes servidores usando la clase FileLock. Pero esto no funciona para los hilos dentro del mismo proceso (contenedor de servlets) ya que los bloqueos de archivos están disponibles en todo el proceso.Usando un archivo separado para sincronización
Podría crear un archivo separado que indique que un proceso está leyendo o escribiendo en el archivo. Esta solución funciona para todos los hilos pero tiene varios inconvenientes:- Actuación. Crear, eliminar y verificar archivos son operaciones bastante lentas. Las implementaciones de bajo peso con un archivo de sincronización evitarán la lectura paralela del archivo.
- El archivo de sincronización permanecerá después de un bloqueo de JVM y será necesario realizar una limpieza manual.
- Ya hemos tenido problemas extraños al eliminar archivos en los sistemas de archivos de red.
Usando mensajería
Podríamos implementar un sistema de mensajería que los hilos usarían para coordinar el acceso al archivo. Pero esto parece demasiado complejo para este problema. Y de nuevo: el rendimiento será pobre.
¿Alguna idea?
A. Parece que es hora de una base de datos :-). En lugar de tener un archivo compartido, ¿qué ocurre con el almacenamiento de los datos en una base de datos?
B. Alternativamente - estratificación:
- Bloquear hilos dentro de un proceso con un bloqueo sincronizado estándar.
- Bloquee interproceso / máquina con un tipo de bloqueo basado en archivo, por ejemplo, cree un directorio para mantener el bloqueo.
Nest 2 dentro de 1.
Todavía tiene el problema de limpieza.
C. ¿Alternativamente algún tipo de estrategia de escritura / cambio de nombre de archivo nuevo para que el lector no necesite bloquear tal vez?
Ha enumerado las posibles soluciones, excepto la más obvia: eliminar la dependencia de ese archivo
¿Hay alguna otra manera para que los hilos obtengan esos datos en lugar de leerlos desde un archivo? ¿Qué hay de la configuración de algún tipo de proceso que es responsable de coordinar el acceso a esa información en lugar de tener todos los hilos leer el archivo.
Usando java.nio.channels.FileLock, con un ReadWriteLock.
Si yo fuera tú, escondería File, FileChannel y FileOutputStream de todos los códigos comerciales. Reemplazado con mi propia clase de adaptador simple, como un DAO.
p.ej
abstract class MyWriter{
private FileChannel file;
public void writeSomething(byte[] b){
// get VM scope write lock here
// get file lock here
// do write
// release file lock
// release readwritelock lock
}
}
La solución más simple es crear otro proceso (servicio web o lo que sea más simple para usted). Solo este proceso lee / escribe el archivo y escucha las solicitudes de lectura / escritura de otros servicios.
Si bien podría parecer que esto es más lento que usar el recurso compartido de red directamente, ese no es necesariamente el caso: usar un uso compartido de red significa usar un cliente / servidor integrado en su sistema operativo (que hace exactamente eso: enviar solicitudes de lectura / escritura a el servidor que ofrece el recurso compartido).
Dado que su servicio está optimizado para la tarea (en lugar de ser un servicio general de "servir archivo"), incluso podría ser más rápido.
Si solo necesita escribir el archivo pocas veces, ¿qué tal si escribe el archivo con un nombre temporal y luego usa el cambio de nombre para que los lectores lo vean?
Sin embargo, esto solo funciona de manera confiable con los sistemas de archivos Unix. En Windows, tendrá que manejar el caso de que algún proceso tenga el archivo abierto (para leer). En este caso, el cambio de nombre fallará. Inténtalo de nuevo hasta que el cambio de nombre tenga éxito.
Sugiero que pruebe esto exhaustivamente porque podría encontrarse con congestión: hay tantas solicitudes de lectura que la tarea del escritor no puede reemplazar el archivo durante mucho tiempo.
Si ese es el caso, haga que los lectores verifiquen el archivo temporal y esperen unos minutos con la próxima lectura hasta que el archivo desaparezca.