style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Dudas con Hilos

Hola buenas tardes, de antemano un saludo a la comunidad.

Como he leido en otros foros, es nefasto que algunos pidan casi que le ayuden a hacer la tarea. en mi caso es distinto, quiciera solo me dieran una orientacion, de la investigacion posterior yo continuare.

Tengo un proyecto, que este buscará dentro de una tabla de mysql los valores numericos, y dependiendo del valor encontrado ejecutará un procedimiento de un jar exterior.

ha lo que he leido de los hilos, son procesos lijeros que se ejecutan como parte independiente del programa padre. y es precisamente lo que busco ( que el programa padre continue buscando valores numericos en la tabla de mysql y los hilos ejecutandose independiente ). Pero me surjen bastantes dudas.

1. Dependiendo de los valores numerico encontrados en la tabla de mysql, seran los procedimientos a llamar del jar exterior. Tendre que hacer varios hilos entonces.?

2. si es el caso de crear varios hilos, como sabre cuales ya estan colgados y poder forzarlos a terminar.

********
Timer INICIO
Buscar Hilos con tiempo en ejecucion mayor a X min > 0 , Forzar a terminarlos

1. Buscar bloque de registros en tabla mysql, con valores X INICIO
Registros >0 llamar Hilo a ejecutar procedimiento de jar externo X
1. Buscar bloque de registros, con valores X FIN

2. Buscar bloque de registros en tabla mysql, con valores Y INICIO
Registros >0 llamar Hilo a ejecutar procedimiento de jar externo Y
2. Buscar bloque de registros, con valores Y FIN
....
....
n...
Timer FIN

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

¿Existe forma en que no

¿Existe forma en que no cuelgues hilos? Me refiero a ¿porque habría de colgarse en primer lugar? ¿ Es una condición normal y esperada?

Pregunta sobre el proceso que esta en el jar ¿Vas a llamarlo como un programa externo a propósito? Los jars, si son incluídos en el proyecto pueden ser ejecutados dentro de la misma máquina virtual, no sé si sepas esto y quieres de todas formas crear una nueva VM para cada proceso.

Ahora, aquí va alguna guía:

Si lo que quieres es llamar a un proceso externo ( un jar por ejemplo ) puedes utilizar la clase ProcessBuilder y dejar que el sistema operativo cree la nueva máquina virtual y todo.

Si quieres llamar a una clase dentro de tu programa, entonces sí , puedes usar los hilos.

Si usas hilos, la forma más fácil de detenerlos es preguntar controlarlo en un loop si una condición se cumpló o no:

.....
while ( sigue ) {
   ....
   sigue = hayQuePararlo();// por ejemplo si ya excedió el tiempo de ejecución máximo
   ...
}

Espero que esto te sirva de guía y cuando tengas algo más concreto no dudes en preguntar de nuevo.

Saludos.

Gracias por tu apoyo

Oscar, muchas gracias por tu apoyo, en este caso se va a llamar un procedimiento de un jar externo. me voy a enfocar entonces por la clase ProcessBuilder.

Saludos

ProcessBuilder

Hice la siguientes pruebas con ProcessBuilder,

1. genere un jar, un simple System.out.println("Test System out Funcionando desde jar");

package test_systemout;

public class Main {
    public static void main(String[] args) {
        System.out.println("Test System out Funcionando desde jar");
    }
}

a este jar lo estoy llamando desde otro

    public static void main(String[] args) {      
        ProcessBuilder pb = new ProcessBuilder( "C:/Users/Test_SystemOut.jar" );
        try {
            Process p = pb.start();
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

El error que me arroja es referente a aplicaciones Win32 ...

java.io.IOException: Cannot run program "C:/Users/Test_SystemOut.jar": CreateProcess error=193, %1 is not a valid Win32 application
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
at control_eventos.Main.main(Main.java:28)
Caused by: java.io.IOException: CreateProcess error=193, %1 is not a valid Win32 application
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.(ProcessImpl.java:188)
at java.lang.ProcessImpl.start(ProcessImpl.java:132)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1021)
... 1 more

Continuare investigando como ejecutar un jar desde java....gracias nuevamente

El jar no es ejecutable

Por si solo un archivo JAR no puede ser ejecutable. Lo que puedes hacer es llamar a java (que si es ejecutable). Si usas windows quedaría así

ProcessBuilder pb = new ProcessBuilder( "java -jar C:/Users/Test_SystemOut.jar" );

ah pero por alguna razón (que no se cual) tienes que mandar a llamar al cmd de windows. entonces tienes que agregar cmd.exe /c antes del llamado a java.exe

MMmmm echale un lente a este post, quizás te sirva si estas ejecutando otro programa en Java

TimerTask

Hay una cháchara que se llama TimerTask y te puede ayudar a disparar tareas en hilos independientes cada cierto intervalo de tiempo.
   

Imagen de benek

Échale un vistazo a la API de

Échale un vistazo a la API de concurrencia de Java, con la clase Executors puedes crear varios tipos de thread pools y hay de varios colores y sabores para que elijas cómo quieres que se comporte la ejecución de tus hilos. Échale un vistazo a esta entrada.

Esto en conjunto con el ProcessBuilder que ya te sugirieron, porque según entendí no quieres lanzar una sino varias ejecuciones del jar concurrentemente.

Saludos.

Imagen de benek

Pues ya de una vez un ejemplo

Pues ya de una vez un ejemplo sencillo y rápido de un newSingleThreadExecutor, según su descripción en la liga que te pasé es:

newSingleThreadExecutor() crea un pool de un solo thread, con una cola en donde se ponen las tareas a procesar; el thread toma una tarea de la cola, la procesa y toma la siguiente, en un ciclo. Similar a la segunda opción sin thread pools; llegan 10 tareas, y se van a procesar de manera secuencial, las siguientes 5 se van a encolar y se procesarán cuando se terminen las primeras 10, y las ultimas 20 se procesarán una tras otra. La ventaja que ofrece este esquema es que cuando se necesita realizar algo asi, ya no se tiene que codificar desde cero, sino que simplemente se puede usar este pool de un solo thread, el cual además tiene la ventaja de que si ocurre una excepción durante la ejecución de una tarea, no se detiene la ejecución de las siguientes.

Y aquí el ejemplo, en este caso el thread pool recibe Runnables que imprimen "Pong!" y esperan dos segundos:

package org.javamexico.executors;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author benek
 *         Date: 03/02/12
 *         Time: 01:40
 *         javamexico.org
 */

public class PruebaExecutors {

    public static void main(String[] args) {

        ExecutorService executor = Executors.newSingleThreadExecutor();

        for (int i = 0; i < 10; i++){
            executor.execute(new Runnable(){
                public void run(){
                    System.out.println("Pong!");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

}

Es sólo un ejemplo, pero así puedes comenzar a jugar con los demás tipos de thread pools.

Saludos.

No funciona de la misma

No funciona de la misma manera que no funciona escribir en la linea de comandos directamente:

c:/Users/Test_SystemOut.jar

Tienes que escribir:

java -cp C:/Users/Test_SystemOut.jar  test_systemout.Main

O bien escribir:

java -jar c:/Users/Test_SystemOut.jar

Si tu jar tiene un manifest especificando la clase principal.

Lo mejor con el ProcessBuilder es escribir cada opción como un string diferente, así:

ProcessBuilder builder = new ProcessBuilder( "java", "-jar", "c:/Blah/blah.jar");

:D

Ejecutar jar

Como mencionaste me funciono llamando antes el cmd, ya pude ejecutar un jar Externo.

Runtime.getRuntime().exec("cmd /c start java -jar C:/Users/Test_SystemOut.jar");

ahora me comentan que llamare diferentes jar, dependiendo de una variable numerica, ahora el problema que tengo es como podre identificar cual ejecucion de los jar esta bloqueada o tiene mas de X tiempo, para forzarla a cerrar. Desconozco si puedo obtener un id de cada jar que ejecute.

Gracias a todos por su apoyo,

No es necesario el "cmd"

No es necesario el "cmd" :

C:\oreyes>dir

02/03/2012  06:48 PM    <DIR>          .
02/03/2012  06:48 PM    <DIR>          ..
02/03/2012  06:16 PM               298 A.java
02/03/2012  06:43 PM               211 B.java
02/03/2012  06:41 PM                17 m.mf

C:\oreyes>type A.java B.java m.mf

A.java

package x;
import java.io.*;

public class A {
   public static void main( String ... args ) throws Exception {
       File f = new File("salida.txt");
       PrintStream out = new PrintStream( new FileOutputStream( f ) );
       out.println("Hola mundo jar");
       out.close();
    }
}
B.java

package x;

public class B {
   public static void main( String ... args ) throws Exception {
      ProcessBuilder p = new ProcessBuilder("java" , "-jar", "c:/oreyes/x.jar" );
      p.start();
   }
}

m.mf

Main-Class: x.A

C:\oreyes>javac -d . A.java B.java

C:\oreyes>jar -cmf m.mf x.jar x

C:\oreyes>java -cp . x.B

C:\oreyes>type salida.txt
Hola mundo jar

Corre bien así

Por cierto para que puedas

Por cierto para que puedas matar un proceso que se quedó colgado puedes utilizar el método: interrupt() de la clase thread...

¬¬

Bueno para no tener que escribir todo de nuevo, ve esta respuesta en StackOverflow:

http://stackoverflow.com/questions/808276/how-to-add-a-timeout-value-whe...

Esta super interesante y muy sencilla.

Por cierto, esa respuesta viene usando Runtime.exec, pero desde la v1.5 ProcessBuilder es lo que se debe de usar.

Saludos.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">