Threads y Sincronización
Los Threads y la sincronización se explicaron en la lección
Miscelánea.
Esta sección describe en general los problemas que el desarrollador de proveedores de servicio
podrían encontrar con respecto al acceso multi-thread y el uso de los threads en los
proveedores de servicio.
Implementaciones de Contexto
El JNDI define el interface
Context y sus subinterfaces con los que se debe implementar un
proveedor de servicio. La seguridad de los threads con respecto al acceso concurrente es un
problema de implementación. Sin embargo, el JNDI hace algunas recomendaciones de sentido
común sobre lo que el usuario del API y el proveedor de servicio deberían esperar:
- El acceso a un sólo ejemplar de Context
debe estar sincronizado.
- Los accesos a ejemplares Context separados no tienen que
estar sincronizados, incluso cuando esos ejemplares de Context
están relacionados.
La primera regla significa que el proveedor de servicio no tiene que preocuparse de proteger los
accesos a los recursos usados por un sólo ejemplar de Context
contra accesos concurrentes multi-thread. Los llamadores son responsables de sincronizar sus
accesos entre ellos mismos. Esta regla permite a las implementaciones de contexto ser
optimizadas para su modo de uso de threads más común.
La segunda regla recuerda a los escritores de proveedores de servicio que cuando los ejemplares
de Context de la misma implementación de contexto comparten
recursos, esos recursos deben protegerse contra accesos concurrentes. Por ejemplo, varios
ejemplares de Context normalmente comparten la misma conexión
de red subyacente. En este caso deberíamos proteger a la conexión de red contra accesos
concurrentes. Esta regla está motivada por el hehco de que los llamadores no pueden tener
cuidado de ninguna relación subyacente entre diferentes ejemplares de
Context y seguramente no podrán sincronizar sus accesos a
diferentes ejemplares de Context. Por lo tanto el proveedor de
servicio debe asegurarse que diferentes ejemplares Context
se comportan como entidades individuales e independientes y ocultan cualquier relación.
Implementaciones de Factorías
Un objeto que implemente cualquiera de los siguiente interfaces y clases abstractas (y sus
subinterfaces) debe ser re-entrante. Es decir, varios threas deberían poder llamar a métodos de
un sólo ejemplar de una factoría concurrentemente.
La mayoría de las factorías no tienen estado, por eso este requerimiento de re-entrada no es
mucho más que una imposición de la implementación.
Uso de Threads
Los threads son herramientas útiles para construir sistemas de software como una implementación
de contexto, especialmente cuando la implementación necesita tratar con la red. De hecho, los
threads son indispensables si una implementación de contexto va a soportar notificación de
eventos como se describió en el paquete
javax.naming.event (ver la lección Notificación de Eventos).
Podríamos usar threads cuando construyamos los componentes de un proveedor de servicio. Sin
embargo, debemos tener cuidado ya que la plataforma
Java 2 Platform, Enterprise Edition,
restringe componentes como los
Enterprise JavaBeans de
crear threads. Esta restricción significa que si nuestro proveedor de servicio necesita crear
threads debería hacerlo dentro de un bloque doPrivileged. Esto
permite al contenedor del componente conceder el permiso para que el proveedor de servicio
cree un thread sin concederselo al componente.
Aquí tenemos un ejemplo de un método de utilidad que realiza la creación de un thread
dentro de un bloquedoPrivileged:
private Thread createThread(final Runnable r) {
return (Thread) AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
return new Thread(r);
}
}
);
}