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

Threads.

Estas en el tema de Threads. en el foro de Java en Foros del Web. Hola, buenos días. Necesito un poco de ayuda para entender esto de los threads. Tengo que lanzar 2 procesos, el primero trata una serie de ...
  #1 (permalink)  
Antiguo 04/05/2009, 08:18
 
Fecha de Ingreso: junio-2008
Ubicación: Madrid
Mensajes: 73
Antigüedad: 15 años, 10 meses
Puntos: 1
Threads.

Hola, buenos días.

Necesito un poco de ayuda para entender esto de los threads.

Tengo que lanzar 2 procesos, el primero trata una serie de ficheros de sistema local y el segundo los crea.

Necesito que el primero lance al segundo y espere a que termine, pero no consigo que funcione correctamente, creo que estoy haciendo algo mal.

Les dejo el código:

Código:
Thread hilo1 = new Thread(new Runnable(){
    public void run(){
       try{
          //Espero
          wait();
          // ... Aqui se leen los ficheros ...
       }catch(Exception e){}
    }
});

Thread hilo2 = new Thread(new Runnable(){
     public void run(){
          // ... Aqui se generán los ficheros ...
          notifyAll();
      }
});

hilo1.start();
hilo2.start();
Gracias por vuestro tiempo y ayuda.

Última edición por Wolfchamane; 04/05/2009 a las 08:19 Razón: cambios en el código
  #2 (permalink)  
Antiguo 04/05/2009, 08:53
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Respuesta: Threads.

El wait y el notifyAll de ambos threads no estan relacionados, ya que no son sobre el mismo objeto, así que el thread 1 se quedará parado para siempre.

Para los threads se "coordinen", tienen que trabajar sobre el mismo "monitor".

De todas formas, si necesitas que un Thread espere a que otro termine, tienes el método join().

Te recomiendo revisar un buen tutorial de programación concurrente y analizarlo con calma, ya que no es un tema simple.

S!
__________________
Para obtener respuestas, pregunta de forma inteligente o si no, pregunta lo que quieras que yo contestaré lo que me dé la gana.
  #3 (permalink)  
Antiguo 04/05/2009, 09:27
 
Fecha de Ingreso: junio-2008
Ubicación: Madrid
Mensajes: 73
Antigüedad: 15 años, 10 meses
Puntos: 1
Respuesta: Threads.

Ya, estube buscando información al respecto, y leí acerca del método synchronized (si se escribe así).

Pero según estoy viendo la solución pasaria por incluir una clase interna, que no contenga nada, y de la cual se relacionen los dos hilos, ¿verdad?

Por ejemplo:
Código:
class Objeto{
  private boolean estado = false;
  public boolean getEstado(){ return estado;}
  public void setEstado(boolean estado) { this.estado = estado; }
}
E incluir las siguientes modificaciones,

Código:
Thread hilo1 = new Thread(new Runnable(){
    Objeto ob = new Objeto();
    public void run(){
       try{
          //Espero
          while(ob.getEstado == false){
              wait();
          }
          // ... Aqui se leen los ficheros ...
       }catch(Exception e){}
    }
});

Thread hilo2 = new Thread(new Runnable(){
     Objeto ob = new Objeto();
     public void run(){
          // ... Aqui se generán los ficheros ...
          ob.setEstado(true);
      }
});

hilo1.start();
hilo2.start();
¿me sigo equivocando?

Última edición por Wolfchamane; 04/05/2009 a las 09:28 Razón: modificaciones en el código
  #4 (permalink)  
Antiguo 04/05/2009, 16:12
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Respuesta: Threads.

¿Lo has probado?

Cada Thread tiene su propio Objeto, así que siguen sin sincronizarse juntos.

S!
__________________
Para obtener respuestas, pregunta de forma inteligente o si no, pregunta lo que quieras que yo contestaré lo que me dé la gana.
  #5 (permalink)  
Antiguo 05/05/2009, 01:15
 
Fecha de Ingreso: junio-2008
Ubicación: Madrid
Mensajes: 73
Antigüedad: 15 años, 10 meses
Puntos: 1
Respuesta: Threads.

Vale, ya tengo la solución, funciona y es lo que busco, salvo por un pequeño problema.

He aqui el código ejemplo:

Código:
package pruebas3;
import java.util.Random;
public class MiPrueba {
public static void main(String args[]){

    class Objeto{
	private boolean estado = false;
	   public boolean getEstado(){
	       return estado;
	   }
	   public void setEstado(boolean estado){
	       this.estado = estado;
	   }
    }

    final Objeto ob = new Objeto();

    Thread hilo1 = new Thread(new Runnable(){
	public void run(){
	    System.out.println("Principio HILO 1");
	        if(ob.getEstado() == false){
		   try{
		      wait();
		   }catch(InterruptedException e){}
		}
		else
		   System.out.println("Fin HILO 1");
	}
    });
		
    Thread hilo2 = new Thread(new Runnable(){
	public void run(){
	    try{
		System.out.println("Principio HILO 2");
		Random rnd = new Random(2);
		int x;
		do{
		    ob.setEstado(false);
		    x = rnd.nextInt(6);
		    System.out.println("Aleatorio: "+x);
		}while(x != 2);
		ob.setEstado(true);
		System.out.println("Fin HILO 2");
		notifyAll();
            }catch(Exception e){}
	}
     });
		
      hilo1.start();
      hilo2.start();
}
}
El problema reside en que al parecer se necesitan varias ejecuciones para que ambos threads terminen, ya que notifyAll() no parece generar una respuesta firme en todos los casos, y como consecuencia hilo1 se queda en ocasiones esperando.

¿Cómo puedo solucionarlo?

Última edición por Wolfchamane; 05/05/2009 a las 01:20 Razón: modificación
  #6 (permalink)  
Antiguo 05/05/2009, 02:30
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Respuesta: Threads.

El problema es que estás presuponiendo que hilo1 se ejecutara y quedará esperando en el wait() antes de que hilo2 alcance el notifyAll(), lo cual es mucho suponer. Si no ocurre eso, el Thread 1 se queda parado para siempre, ya que el notifyAll() no "se acumula".

S!
__________________
Para obtener respuestas, pregunta de forma inteligente o si no, pregunta lo que quieras que yo contestaré lo que me dé la gana.
  #7 (permalink)  
Antiguo 05/05/2009, 06:37
 
Fecha de Ingreso: junio-2008
Ubicación: Madrid
Mensajes: 73
Antigüedad: 15 años, 10 meses
Puntos: 1
Respuesta: Threads.

¿Pero en ese caso, cómo hago para que hilo1 se quede esperando hasta que hilo2 alcance notifyAll()?

Todos los ejemplos, manuales y tutoriales que estoy leyendo por internet no muestran un caso claro en el que un thread se quede esperando a que otro concluya, todos más bien intenta explicar como entrelazar dos threads y que operen al mismo tiempo.
  #8 (permalink)  
Antiguo 05/05/2009, 07:15
 
Fecha de Ingreso: junio-2008
Ubicación: Madrid
Mensajes: 73
Antigüedad: 15 años, 10 meses
Puntos: 1
De acuerdo Respuesta: Threads.

Vale, yo mismo me contesto.
No hay nada como volver a leer detenidamente.

He aqui la solución al problema de cómo lanzar un hilo y que espere a que se termine otro.

Código:
class Hilo1 extends Thread{
	
  public void run(){
      try{
        System.out.println("Hilo1 comienza ...");
        Hilo2 h2 = new Hilo2();
        h2.start();
        h2.join();
        System.out.println("Hilo1 finaliza ...");
      }catch(Exception e){}
  }
}

class Hilo2 extends Thread{
	
    public void run(){
        try{
            System.out.println("Hilo2 comienza ...");
            for (int i=0; i<10; i++){
                System.out.println("Iter: "+(i+1));
                sleep(1000);
            }
            System.out.println("Hilo2 finaliza ...");
            notify();
        }catch(Exception e){}
    }
}

public class MiPrueba5 {
	
    public static void main(String args[]){
        try{
            System.out.println("Comienzo ...");
            Hilo1 h1 = new Hilo1();
            h1.start();
            h1.join();
            System.out.println("Finalizo ...");
        }catch(Exception e){}
    }
}
La salida por pantalla debería ser:
Comienzo ...
Hilo1 comienza ...
Hilo2 comienza ...
Iter: 1
Iter: 2
Iter: 3
Iter: 4
Iter: 5
Iter: 6
Iter: 7
Iter: 8
Iter: 9
Iter: 10
Hilo2 finaliza ...
Hilo1 finaliza ...
Finalizo ...


Muchas gracias por la ayuda GreenEyed, +Karma para ti xD

Última edición por Wolfchamane; 05/05/2009 a las 07:15 Razón: actualización
  #9 (permalink)  
Antiguo 05/05/2009, 14:15
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Respuesta: Threads.

Esa solución es buena, pero si lo miras atentamente, es como si hicieras las llamadas secuencialmente.

Otra opcion sería que creases el Hilo2 primero, se lo pasas al Hilo1 en el constructor y puedes arrancarlos uno detras de otro, simplemente que el Hilo1 hace un join del Hilo2 cuando ya no pueda seguir trabajando más y deba esperar al Hilo2.

Cuando varios hilos se han de sincronizar, lo habitual y necesario es que tengan algun elemento(objeto) en comun, que se les pasa en el constructor o algun metodo antes de hacerles el start. Puede ser una referencia a otro Thread directamente, o al objeto sobre el que tienen que trabajar.

De todas formas, con dos hilos así artificiales es dificil hacerse una idea, así que no te preocupes si no te queda la idea perfecta. Para tener las ideas más claras te recomendaría tratar de implementar algún problema típico de concurrencia, como el acceso a una cola por productores y consumidores, el problema de los filósofos chinos o alguno similar.

S!
__________________
Para obtener respuestas, pregunta de forma inteligente o si no, pregunta lo que quieras que yo contestaré lo que me dé la gana.
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 08:52.