2010-02-18 17 views
7

Entiendo el concepto detrás del hilo y he escrito hilos en otros idiomas, pero tengo problemas para entender cómo adaptarlos a mis necesidades en Java.Métodos Java Ejecutando en hilos

Básicamente en este momento tengo un vector de objetos, que se leen de un archivo secuencialmente. El archivo tiene una lista de eventos, que deben suceder al mismo tiempo, por lo que no es una opción esperar a que termine un evento, lo que lleva de 20 a 30 segundos.

Hay solo un par de métodos en el objeto que tratan estos eventos. Sin embargo, al mirar los tutoriales, los objetos deben extender/implementar subprocesos/ejecutable; sin embargo, si el objeto está en un subproceso, hacer una llamada a ese objeto parece suceder secuencialmente de todos modos.

Se agradecería una información adicional ya que claramente me falta algo, ¡no estoy muy seguro de qué!

Para resumir, ¿cómo puedo ejecutar un solo método usando un hilo?

Respuesta

5

Para iniciar un hilo, llame al start() en una instancia de Thread o una de sus subcategorías. El método start() devuelve inmediatamente. Al mismo tiempo, el otro subproceso (el encarnado por la instancia Thread) despega y continúa con la ejecución del método run() de la instancia Thread.

Gestionar hilos no es tan fácil como parece. Para una API más suave, intente utilizar un Executor (consulte las clases en java.util.concurrent).

+1

Corregí el nombre del paquete por usted. – Powerlord

+1

¿cómo especifico que run() ejecuta los métodos correctos? como no puedo pasar ningún parámetro a través de ejecutar? – john

+0

@john: puede inyectar los parámetros que desee en el constructor de Thread/Runnable. – Nelson

1

Thomas ya ha facilitado los detalles técnicos. Voy a tratar de enfocarme en la lógica.

Esto es lo que puedo sugerir a partir de mi comprensión de su problema.

Digamos que tiene una colección de objetos de tipo X (o tal vez incluso una mezcla de diferentes tipos). Debe llamar a los métodos foo y/o bar en estos objetos en función de algún evento especificado. Entonces, quizás tengas una segunda colección que los guarde.

Tenemos dos objetos List (uno para los objetos X y otro para los eventos).

Ahora, tenemos una función ejecutar que tomará X, y el evento, y llama a foo o barra. Este método de ejecución puede envolverse en un hilo y ejecutarse simultáneamente. Cada uno de estos subprocesos puede tomar un objeto de la lista, incrementar el contador y ejecutar foo/bar. Una vez hecho esto, verifique el contador y tome el siguiente de la lista. Puede tener 5 o más de estos subprocesos trabajando en la lista.

Por lo tanto, como vemos, los objetos provenientes del archivo no tienen que ser los objetos Thread.

Debe tener mucho cuidado de que la Lista y el contador estén sincronizados. Estructuras de datos mucho mejores son posibles. Me estoy apegando a uno tosco para facilitar la comprensión.

Espero que esto ayude.

0

La clave para los hilos es recordar que cada tarea que se debe ejecutar debe estar en su propio hilo. Las tareas que se ejecutan en el mismo subproceso se ejecutarán secuencialmente. Dividir las tareas concurrentes entre hilos separados le permitirá hacer su procesamiento concurrente requerido.

+0

Si bien ese es un buen punto, no estoy muy seguro de que responda la pregunta ... ¿Seguro que se te ocurre cómo responder la parte sobre tratar específicamente con los hilos en Java? –

2

Lo mejor que puede hacer en Java es crear otra clase que se lleva en los datos que necesita para procesar y lleva a cabo todo lo que se necesita para llevar a cabo:

class Worker implements Runnable{ 

    Object mydata; 
    Worker(Object data) 
    { 
     mydata = data; 
    } 

    @override 
    void run() 
    { 
     //process the data 
     System.out.println(data.toString()); 

     //or if you want to use your class then: 
     YourClass yc = (YourClass)myData; 
     yc.methodB(); 
    } 
} 

class YourClass 
{ 
    private final ExecutorService executor = Executors.newCachedThreadPool(); 
    private ArrayList<Object> list; 
    YourClass() 
    { 
     list = new ArrayList<Object>(); 
     list.add(new Object()); 
     ... 
     ... 
     list.add(new Object()); 
    } 

    void methodA() 
    { 
     for(Object item : list) 
     { 
      // Create a new thread with the worker class taking the data 
      executor.execute(new Worker(item)); 
     } 
    } 

    void methodB(){/*do something else here*/} 
} 

Tenga en cuenta que en lugar de obtener los datos, puede pase la clase real en la que necesita que se invoque el método:

executor.execute (new Worker (new MyClass()));

En el método de ejecución de la clase Worker invocas lo que necesites invocar en MyClass ... el ejecutor crea un nuevo hilo y ejecuta llamadas en tu Worker. Cada Trabajador se ejecutará en un hilo separado y será paralelo.

+0

Por cierto: en el método A puede leer los objetos del archivo, ejecutar un nuevo Trabajador con cada objeto que obtuvo del archivo y continuar leyendo más objetos mientras el trabajador está procesando el elemento. – Kiril

+0

Gracias, eso parece ser exactamente la solución que estoy buscando, sin embargo, ¿hay alguna manera de asegurarme de que cada vez que se llame al método se ejecute usando un nuevo hilo o uno que haya terminado? – john

+0

@john Se le GARANTIZA que cada vez que ejecute ejecutar ejecutará su método en un "nuevo hilo". Para ser más precisos, la documentación de Java dice que el método "ejecutar" "ejecuta la tarea dada alguna vez en el futuro. La tarea puede ejecutarse en un nuevo hilo o en un hilo mancomunado existente". Desde su perspectiva, no hay diferencia entre un hilo mancomunado existente o un hilo nuevo. "Algún momento en el futuro" simplemente significa que el planificador de hilos decide cuándo ejecutar el hilo (lo mismo que llamar a un nuevo hilo (...)). – Kiril