Llamadas simultaneas al mismo método

Pedro
02 de Noviembre del 2005
Hola,

He creado una clase que gestiona envios por un socket, siguiendo el patron singleton. Para hacer el envio, la clase tiene un metodo que es el encargado de mandar por el socket lo que recibe como parámetro.

La cosa es, que multiples hilos tomarán la instancia vigente de la clase (singleton), para llamar a ese método y hacer el envio de datos por el socket. Entonces, no se si esto plantea problemas de concurrencia y que se produzcan bloqueos por acceder al mismo método del mismo objeto paralelamente, ya que además este envía por el mismo socket.
Supongo que sí, ya que se podrían mezlcar mensajes.
¿¿Como sería una forma eficiente y sencilla de hacer esto?? ... me gustaría seguir manteniendo el uso del patron para tener el "gestor de envios" bien definido y siendo único.

Muchas gracias
Pedro

nicokiki
02 de Noviembre del 2005
Hola!!!

Deberias sincronizarlo (synchronized) al metodo

Salu2!!!

chuidiang
02 de Noviembre del 2005
Buenas:

En principio no hay problema con lo que es el código en sí. El problema es usar el mismo socket. Si dos hilos envían mensajes a la vez, es posibles que los bytes de ambos mensajes salgan entremezclados por el socket. El que va a recibir no se enterará de nada, le llegan cosas raras.

Pasa lo mismo con la lectura. Si dos hilos intentan leer a la vez, es posible que cada uno consiga un cacho del mensaje.

Todo esto es más probable cuanto más grandes sean los mensajes.

Para evitarlo, dentro de la clase que envia y recibe del socket, tendras una instancia de Socket o algo similar. Al leer o recibir mensajes ahi dentro, hazlo asi

public Object dameMensaje()
{
synchronized (instanciaSocket)
{
// codigo para leer un mensaje completo
}
return mensaje
}


public void enviaMensaje (Object mensaje)
{
synchronized (instanciaSocket)
{
// codigo para enviar el mensaje completo.
}
}

Una pequeña tontería. Los sockets son bidireccionales. Un hilo podría leer un mensaje y otro enviar a la vez. Si lo haces como te estoy diciendo, eliminas esa posibilidad. Si tienes interés en que se pueda hacer a la vez, en vez de usar instanciaSocket, tendrías que usar para sincronizar los inputStream y outputStream que obtienes del socket que es con los que realmente escribes.

Se bueno.

Pedro
02 de Noviembre del 2005
Creo que voy a optar por sincronizar el metodo que hace los envios. En cuanto a envío-recepcion no hay problema, porque el socket solo se usará para mandar informacion.

El metodo queda algo así:

public synchronized void send(Message message)
{

envio = new BufferedWriter(new OutputStreamWriter(socketEnvios));

try
{

envio.write(message);
envio.flush();

}
catch (IOException e)
{
System.err.println("Error");
}
}

Así cada hilo que quiera enviar un mensaje, si el metodo está ocupado tendrán que esperar ...

¿Todo bien, no???

Muchas gracias a los dos.