Foros del Web » Programación para mayores de 30 ;) » Java »

Consulta synchronized objeto

Estas en el tema de Consulta synchronized objeto en el foro de Java en Foros del Web. Hola a todos, estoy haciendo pruebas con el synchronized para que varios hilos no me machaquen una información determinada y he estado realizando la siguiente ...
  #1 (permalink)  
Antiguo 16/08/2011, 07:15
 
Fecha de Ingreso: febrero-2011
Mensajes: 672
Antigüedad: 13 años, 2 meses
Puntos: 78
Consulta synchronized objeto

Hola a todos,
estoy haciendo pruebas con el synchronized para que varios hilos no me machaquen una información determinada y he estado realizando la siguiente prueba, que no se si hago algo mal o es el concepto que se me escapa.

Hilo1

Código PHP:
public void run(){
        try{
            
FileWriter fr = new FileWriter(new File("C:\\TEST.txt"), true);
            
synchronized (fr) {
                
                for (
int i=0;i<10000;i++){
                    
fr.write("A" "\r\n");
                }
            
            
fr.flush();
            
fr.close();
            }
                
        }catch (
Exception e){
            
e.getMessage();
        } 
Hilo2

Código PHP:
public void run(){
        try{
            
            
FileWriter fr = new FileWriter(new File("C:\\TEST.txt"), true);
            
            
synchronized (fr) {
                for (
int i=0;i<10000;i++){
                    
fr.write("B" "\r\n");
                }

            
fr.flush();
            
fr.close();    
            }    
            
        }catch (
Exception e){
            
e.getMessage();
        }
        
    } 
Básicamente hacen lo mismo.

Entiendo que al poner el synchronized cuando entra uno de los dos hilos, el otro se tiene que esperar a que deje de usar el objeto para poder hacer uso de él.

El resultado del escenario actual, es que me encuentro todo mezclado, las lineas del Hilo1 con las del Hilo2.

¿Porque no se espera el segundo hilo a que acabe de escribir el primero?

Muchas gracias a todos por vuestro tiempo y ayuda.

Un saludo.
  #2 (permalink)  
Antiguo 16/08/2011, 18:06
Avatar de Ronruby  
Fecha de Ingreso: julio-2008
Ubicación: 18°30'N, 69°59'W
Mensajes: 4.879
Antigüedad: 15 años, 9 meses
Puntos: 416
Respuesta: Consulta synchronized objeto

El problema esta en que ambos hilos definen su propio método. Con hacer eso, no previenes que se escriba en el archivo uno a la vez ya que ambos hilos tienen su propio bloque sincronizado.

Lo que debes hacer es AISLAR el método que crea el archivo y luego desde el hilo hacer la llamada a ese método.
  #3 (permalink)  
Antiguo 16/08/2011, 19:47
 
Fecha de Ingreso: enero-2008
Mensajes: 197
Antigüedad: 16 años, 3 meses
Puntos: 10
Respuesta: Consulta synchronized objeto

El problema mas bien esta en que cada hilo define su propio objeto fr por lo que es una variable local, las variables locales son thread safe por lo que no estan compartidas con los demas hilos, esto es BUENO no hay que confundir, pero para efectos practicos de tu ejemplo no funciona.

1. Lo que debes hacer es, identificar tu objeto compartido que es, en este caso: FileWriter
2. Declararlo en una clase principal como objeto compartido, simplemente como variable de objeto (puedes usar static tambien)
3. Lanzar tus threads desde la clase principal.
4. Estas bien en sincronizar el bloque nada mas que en lugar de sincronizar la variable local, ahora estaras sincronizando la variable compartida.

Saludos!
  #4 (permalink)  
Antiguo 17/08/2011, 01:13
 
Fecha de Ingreso: febrero-2011
Mensajes: 672
Antigüedad: 13 años, 2 meses
Puntos: 78
Respuesta: Consulta synchronized objeto

Hola hualro y Ronruby,
muchas gracias por vuestras aclaraciones, ahora entiendo bien cómo funciona y el error que estaba teniendo.

Voy a rectificar según me indicais.

Muchas gracias y un saludo.

Athlit
  #5 (permalink)  
Antiguo 18/08/2011, 05:10
 
Fecha de Ingreso: febrero-2011
Mensajes: 672
Antigüedad: 13 años, 2 meses
Puntos: 78
Respuesta: Consulta synchronized objeto

Buenas, he logrado que me "funcionara" aunque el segundo bloque no empieza desde el número 0....

(Abajo del código he puesto la explicación para que se entendiera mejor)


Clase Sincronized1 (principal)

Código PHP:
public class Sincronized1 {

    static 
FileWriter fr;
    
    public 
Sincronized1(){
        try{
        
fr = new FileWriter(new File("C:\\Test.txt"));
        }catch (
Exception e){
            
e.printStackTrace();
        }
    }
    
    public 
void Metodo1(){
        try{

            
Sincronized2 sin2 = new Sincronized2();
            
Sincronized3 sin3 = new Sincronized3();
            
sin2.start();
            
sin3.start();
            
sin2.join();
            
sin3.join();
            
fr.close();
            }catch (
Exception e){
                
e.printStackTrace();
            }
    }
    
    public static 
void main(String[] args) {
        
Sincronized1 sin1 = new Sincronized1();
        
sin1.Metodo1();
    } 
Clase Sincronized2 (HILO1)

Código PHP:
public void run(){
        
Sincronized1 sin1 = new Sincronized1();
        
        
synchronized (sin1.fr) {
            
             
            try{
                for (
int i=0;i<10000;i++){
                    
                    
sin1.fr.write("A" "\r\n");
                    
                }
                
            }catch (
Exception e){
            
System.out.println("Error en " getClass().getName());
            
System.out.println(e.getMessage());
            }
            
            
        } 
Clase Sincronized3 (HILO2)

Código PHP:
public void run(){
        
Sincronized1 sin1 = new Sincronized1();
        
        
synchronized (sin1.fr) {
            
            
            try{
                for (
int i=0;i<10000;i++){
                    
                    
sin1.fr.write("B" "\r\n");
                    
                }

            }catch (
Exception e){
            
System.out.println("Error en " getClass().getName());
            
System.out.println(e.getMessage());
            }
            
            
        } 

SALIDA:

......
A9995
A9996
A9997
A9998
A9999
B90

B91
B92
B93
B94
B95
........

Pienso lo siguiente, a ver que creeis.

Es posible que mientras el Objeto sin1.fr que uso en la Clase sincroniced3 aunqué esté bloqueado, el bucle sigue funcionando y cuando por fin ya está desbloqueado y puede escribir, el bucle ha funcionado 89 vueltas (sin poder escribirlas en fichero)?? Yo pensaba que bloquearía el bucle al estar entre llaves tambien (si es que fuera ese el "problema").

Muchas gracias y un saludo!

Athlit
  #6 (permalink)  
Antiguo 18/08/2011, 07:43
Avatar de Ronruby  
Fecha de Ingreso: julio-2008
Ubicación: 18°30'N, 69°59'W
Mensajes: 4.879
Antigüedad: 15 años, 9 meses
Puntos: 416
Respuesta: Consulta synchronized objeto

Hice una pequena prueba para que verifiques como es que lo debes hacer:
Código Javascript:
Ver original
  1. public static void main(String[] args) throws Exception {
  2.         final SyncTest test = new SyncTest();
  3.  
  4.         Thread hiloUno = new Thread(new Runnable() {
  5.             public void run() {
  6.                 try {
  7.                     test.writeToFile("A");
  8.                 } catch(Exception e) {
  9.  
  10.                 }
  11.             }
  12.         });
  13.  
  14.         Thread hiloDos = new Thread(new Runnable() {
  15.             public void run() {
  16.                 try {
  17.                     test.writeToFile("B");
  18.                 } catch(Exception e) {
  19.  
  20.                 }
  21.             }
  22.         });
  23.  
  24.         hiloUno.start();
  25.         hiloDos.start();
  26.     }
Código Javascript:
Ver original
  1. public void writeToFile(String firstChar) {
  2.  
  3.         synchronized (SyncTest.archivo) {
  4.  
  5.             for(int i = 1; i <= 10; i++) {
  6.                  System.out.println(firstChar + i); //Debes reemplazar esto por la actual escritura
  7.             }
  8.  
  9.         }
  10.  
  11.     }

Debes de aislar el metodo de escritura en tu clase tambien

La clase SyncTest tiene un metodo llamado writeToFile que cree para hacer una pruebita. Al hacerlo de esa manera, solo un hilo escribira a la vez en el archivo.
  #7 (permalink)  
Antiguo 18/08/2011, 08:50
 
Fecha de Ingreso: febrero-2011
Mensajes: 672
Antigüedad: 13 años, 2 meses
Puntos: 78
Respuesta: Consulta synchronized objeto

Hola Ronruby,
en primer lugar muchas gracias por tu tiempo y no solo eso, me has ayudado muchísimo.

Con tu ejemplo me ha quedado bastante más claro, y comprendiéndolo he creado un código desde 0 (pero viene a ser lo mismo) y me ha funcionado a la perfección de modo que si quito el synchronized me sale todo mezclado y al ponerlo me lo imprime por pantalla perfecto.

El problema que tengo ahora es que al hacer lo mismo escribiendo en fichero tengo problemas con el cierre cuando ya tengo creado el Stream, pero lo importante era comprender la idea del synchronized. Para esto último ya me busco la vida a ver como me lo monto.

Muchas gracias por todo y un saludo!!!!

Por si sirve a alguien o si quieres echar un vistazo, adjunto código:

Clase principal
Código Javascript:
Ver original
  1. public void Escritura(String strIDHilo){
  2.         try{
  3.                        
  4.             synchronized(System.out){
  5.                
  6.                 for (int i=0;i<100;i++){
  7.                     System.out.println(i + strIDHilo + "\r\n");
  8.                 }
  9.             }
  10.            
  11.             System.out.println("OK!!");
  12.            
  13.             }catch (Exception e){
  14.                 e.printStackTrace();
  15.             }
  16.     }
  17.    
  18.     public static void main(String[] args) {
  19.         Sincronized2 sin2 = new Sincronized2();
  20.         Sincronized3 sin3 = new Sincronized3();
  21.         sin2.start();
  22.         sin3.start();
  23.     }

Clase sincronized2 (HILO1)
Código Javascript:
Ver original
  1. public void run(){
  2.     try{
  3.         Sincronized1 sin1 = new Sincronized1();
  4.         sin1.Escritura("HILO1");
  5.         }catch (Exception e){
  6.             e.printStackTrace();
  7.         }
  8.    
  9.     }

Clase sincronized3 (HILO2)
Código Javascript:
Ver original
  1. public void run(){
  2.         try{
  3.         Sincronized1 sin1 = new Sincronized1();
  4.         sin1.Escritura("HILO2");
  5.         }catch (Exception e){
  6.             e.printStackTrace();
  7.         }
  8.    
  9.     }

Athlit
  #8 (permalink)  
Antiguo 18/08/2011, 09:41
 
Fecha de Ingreso: febrero-2011
Mensajes: 672
Antigüedad: 13 años, 2 meses
Puntos: 78
Respuesta: Consulta synchronized objeto

Por si alguien tiene un problema parecido al mio, al final de los hilos, con un join() esperamos a que terminen y ya podemos hacer el close().

Un saludo!

Athlit

Etiquetas: objeto
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 15:15.