2011-02-11 13 views
7

Esto es tarea.Eliminar bloqueo de un método

No quiero la solución, solo un pequeño número de enlaces o ideas.

En pocas palabras lo que yo quiero hacer es,

ejemplo simple:

public class Example 
{ 
    public void method() 
    { 
      int x = doThat(); 
      //Call other methods which do not depend on x 
      return; 
    } 
} 

doThat() es un método que se sabe que es mucho tiempo, lo que se traduce en mi programa de bloqueo hasta que los resultados están de vuelta. Y quiero utilizar diferentes métodos de este objeto, pero el programa es frozen hasta que finalice el doThat(). Esos métodos diferentes no necesariamente tienen que invocarse desde el method() utilizado en este ejemplo, pero quizás desde fuera del objeto.

Pensé en usar hilos, pero si tengo una gran cantidad de objetos (más de 1000) esto probablemente no sea muy eficiente (corríjanme si me equivoco, por favor). Supongo que si uso hilos, ¿debo usar un hilo por objeto?

¿Hay alguna otra manera además de los hilos que pueden hacer que el objeto invocado no se bloquee al llamar al doThat();? Si el enhebrado es la única forma, ¿podría proporcionar un enlace?

Sabiendo que las preguntas como esa quedan invalidadas, aceptaré cualquier downvotes. Pero, por favor, solo un enlace sería más que excelente.

Gracias de antemano. Espero que la pregunta esté en línea con las reglas.

Respuesta

3

También me gustaría usar hilos para esto, pero simplemente quería añadir que probablemente sería interesante mirar java.util.concurrent.Executors (para crear agrupaciones de hebras y cuando usted tiene una serie de objetos) y los java.util.concurrent.Future y java.util.concurrent.Callable clases que será le permite iniciar subprocesos que pueden devolver un valor.

Eche un vistazo a concurrency tutorial para obtener más información.

+0

(mi) Común dice que no es posible hacer que un método sea susceptible de ser enhebrado, así que si hago que la clase 'Example' se pueda enhebrar, podré invocar otros métodos de esa clase cuando' method() 'esté bloqueado durante 'doThat()'? – Muggen

+0

la clase de ejemplo no es la que se convertirá en un subproceso. Ejemplo debería ser el encargado de crear su grupo de subprocesos con n posibles subprocesos (Executors.newFixedThreadPool (n)) y luego tendrá que crear su propia clase extendiendo "Callable" para hacer el trabajo (son sus hilos). Su implementación de Callable.call() hará el trabajo (doThat()) y devolverá el resultado del cálculo. Pasa Callables al grupo de subprocesos a través de ExecutorService.submit (invocable) y recupera el resultado a través de Future.get(). Tome nota de que esta última llamada está bloqueando, debe hacerlo justo antes de su regreso. – Kellindil

1

Te recomiendo que crees una clase que implemente Runnable, cuyo método run hace lo que doThat() hace en tu muestra. Entonces puedes invocarlo en un subproceso separado de una manera simple. El Thread class de Java tiene un constructor que toma un ejecutable. Use los métodos run y join.

Saludos Matthias

1

de hilos del curso son la única solución para manejar algunos puestos de trabajo en los antecedentes, pero que no se ven obligados a utilizar un hilo sólo para una única operación a realizar. Puede usar solo un hilo que mantenga una cola de operaciones a realizar, de forma que cada llamada al método haga una nueva entrada en la cola. Tal vez algunos patrones de diseño como "Estrategia" pueden ayudarlo a generalizar el concepto de operación que se realizará, a fin de almacenar "objetos de operación" en la cola del hilo.

1

Desea realizar varias cosas al mismo tiempo, por lo que usar hilos de hecho es el camino a seguir. El Java tutorial concurrency lesson probablemente lo ayude.

1000 subprocesos concurrentes impondrán una gran carga de memoria, porque se asigna una cierta cantidad de memoria de pila para cada subproceso (2 MB?). Sin embargo, si de alguna manera puede asegurarse de que solo habrá un subproceso ejecutándose a la vez, puede tomar el subproceso por enfoque de objeto. Esto requeriría que usted administre que solo se llama al doThat(), si el hilo producido por una invocación anterior en otro objeto ya ha finalizado.

Si no puede asegurarlo fácilmente, el otro enfoque sería construir un hilo de trabajo que lea desde un double ended queue en qué objeto trabajar. El método doThat() simplemente agregaría this al final de la cola, de la cual el hilo de trabajo la extraerá posteriormente. Tienes que sincronizar correctamente cuando accedes a cualquier estructura de datos de hilos concurrentes. Y el hilo principal debería de alguna manera notificar al hilo de trabajo de la condición, que no agregará más objetos a la cola, por lo que el hilo del trabajador puede terminar limpiamente.

Cuestiones relacionadas