2012-05-07 15 views
5

Sé que la seguridad de subprocesos de los sockets de Java se ha discutido en varios subprocesos aquí en stackoverflow, pero no he podido encontrar una respuesta clara a esta pregunta: ¿es seguro tener en la práctica varios hilos simultáneamente escriben en el mismo SocketOutputStream, ¿o existe el riesgo de que los datos enviados desde un hilo se mezclen con los datos de otra banda de rodadura? (Por ejemplo, el receptor en el otro extremo recibe primero la primera mitad del mensaje de un hilo y luego algunos datos del mensaje de otro hilo y luego el resto del mensaje del primer hilo)Seguridad de subprocesos de SocketOutputStream

La razón por la que dije "en la práctica" es que Sé que la clase Socket no está documentada como segura para subprocesos, pero si realmente es segura en las implementaciones actuales, eso es lo suficientemente bueno para mí. La implementación específica que más me llama la atención es que Hotspot se ejecuta en Linux.

Al observar la implementación de la capa de Java de la zona activa, más específicamente la implementación de socketWrite() en SocketOutputStream, parece que debería ser seguro para subprocesos siempre que la implementación nativa de socketWrite0() sea segura. Sin embargo, al observar la implementación de ese método (j2se/src/solaris/native/java/net/SocketOutputStream.c), parece dividir los datos para enviarlos en fragmentos de 64 o 128kb (dependiendo de si se trata de un 64bit JVM) y luego envía los fragmentos en escrituras separadas.

Entonces, para mí, parece que enviar más de 64kb de diferentes hilos no es seguro, pero si es inferior a 64 kb debería ser seguro ... pero podría estar perdiendo algo importante aquí. ¿Alguien más aquí miró esto y llegó a una conclusión diferente?

Respuesta

5

Creo que es realmente mala idea de depender tanto de los detalles de implementación de algo que puede cambiar más allá de su control. Si hace algo como esto, tendrá que controlar muy cuidadosamente las versiones de todo que utiliza para asegurarse de que es lo que espera, y eso es muy difícil de hacer. Y también deberá tener un conjunto de pruebas muy sólido para verificar que la operación multiproceso funcione correctamente, ya que depende de la inspección del código y de los rumores de Randoms en StackOverflow para su solución.

¿Por qué no puede simplemente ajustar el SocketOutputStream en otro OutputStream pasante y luego agregar la sincronización necesaria en ese nivel? Es mucho más seguro hacerlo de esa manera y es mucho menos probable que tenga problemas inesperados en el futuro.

+1

convenido .. usted podría tener un modelo productor/consumidor con un BlockingDeque que los productores (escribe) anexan a y el consumidor (remitente) tira de las cosas fuera de la parte delantera a enviar. – sjr

+0

Gracias por tomarse el tiempo para responder. Si es una buena idea o no, puede ser discutible.Personalmente, no creo que sea necesariamente una mala idea hacer cosas que dependen de una implementación específica. Hay muchas otras razones por las cuales uno podría querer usar Java además de la idea de "escribir una vez en cualquier lugar". Si el rendimiento es crítico, ser capaz de ejecutar su código en cualquier implementación puede ser un requisito que esté dispuesto a abandonar. – oscar11

+0

Sé que, ya sea que se agregue el bloqueo alrededor de las escrituras o se asegure de que solo haya un escritor utilizando un hilo separado y una cola de bloqueo, se "resolverá" el problema. Sin embargo, usar una cola de bloqueo desafortunadamente agregaría demasiada latencia para mis requisitos, y si bien la sincronización del acceso a la escritura lo haría seguro, sería bueno evitarlo si no es realmente necesario. – oscar11

2

Según esta documentación http://www.docjar.com/docs/api/java/net/SocketOutputStream.html, la clase no pretende ser segura para subprocesos y, por lo tanto, se supone que no lo es. Hereda de FileOutputStream, que normalmente la E/S de archivo no es intrínsecamente segura para subprocesos.

Mi consejo es que si la clase está relacionada con el hardware o las comunicaciones, no es segura o "bloqueante". El motivo es que las operaciones de seguridad de subprocesos consumen más tiempo, lo que puede que no te guste. Mi experiencia no está en Java, pero otras bibliotecas son similares en filosofía.

Me di cuenta de que había probado la clase extensamente, pero puede probarla todo el día durante muchos días, y puede que no pruebe nada, mis 2 centavos.

Buena suerte & divertirse con ella.

Tommy Kwee

Cuestiones relacionadas