2009-06-05 9 views
6

tengo un mecanismo bastante estándar en Java para resolver el problema:Migración de concurrencia de Java para Scala concurrencia

  • Los elementos de trabajo deben ser programados para ejecutar en un momento determinado
  • Cada elemento de trabajo debe entonces esperar en una condición de convertirse en verdaderos
  • Los elementos de trabajo debería ser canceladas

La solución que uso es el siguiente:

  1. Tener un planificador de un solo subproceso para programar mis elementos de trabajo
  2. Tener una ExecutorService (que puede ser multi-hilo)
  3. Cada elemento de trabajo programado a continuación, envía el trabajo real a la ExecutorService. El Future devuelto se almacena en caché en un mapa. Un servicio de terminación se utiliza para eliminar el futuro de la caché cuando el trabajo esté terminado
  4. Los productos que se pueden cancelar a través de los futuros de caché

Por supuesto, mi ejecutor tiene que ser al menos tan grande como el número de bloquear elementos de trabajo que espero tener, pero esto no es un problema en la práctica.

Así que ahora estoy codificando en Scala y utilizando el marco actor. Suponiendo que mi elemento de trabajo se puede encapsular en un evento enviado a un actor:

  1. ¿Qué mecanismo utilizaría para programar un elemento de trabajo para un tiempo específico?
  2. Si un elemento de trabajo es un evento enviado a un actor, ¿cómo puedo garantizar que el grupo de subprocesos de respaldo sea más grande que el número de elementos que se pueden bloquear al mismo tiempo
  3. ¿Cómo puedo causar un trabajo programado previamente? artículo que se cancelará?
+0

¿Puede explicar qué significa "una condición que se convierte en realidad"? ¿Es este estado global? ¿Es E/S? – Apocalisp

+0

Solo me refiero a que, como parte del trabajo, el proceso podría tener que bloquearse para que ocurra algo (como que llegue un archivo) –

Respuesta

5

¿Qué mecanismo usaría para programar un elemento de trabajo para un tiempo específico?

Utilizaría un java.util.concurrent.ScheduledExecutorService.

Si un elemento de trabajo es un evento enviado a un actor, ¿cómo me aseguro de que la agrupación de hebras de refuerzo es más grande que el número de elementos que pueden estar bloqueando al mismo tiempo

Este huelgas como un diseño que derrota el esfuerzo de la paralelización. Intenta minimizar o eliminar el bloqueo y el estado global. Estas son barreras a la capacidad de compilación y escalabilidad. Por ejemplo, considere tener un solo hilo dedicado que espere a que lleguen los archivos y luego despide los eventos a los actores. O consulte java.nio para E/S asíncrona sin bloqueo.

No entiendo completamente sus requisitos aquí, pero parece que podría tener un solo hilo/actor buscando eventos de E/S. Luego, como sus "elementos de trabajo" programados, programe los efectos que crean actores no bloqueantes. Haga que esos actores se registren con el hilo/actor de E/S para recibir mensajes sobre eventos de E/S que les interesan.

¿Cómo puedo hacer que se cancele un elemento de trabajo previamente programado?

ScheduledExecutorService returns Futures. Lo que tienes no es un mal diseño en ese sentido. Recógelas en un Mapa y llama a future.cancel().

+0

Tiene toda la razón al pensar que el modelo de "bloqueo de trabajo" es inapropiado y casi lo mismo conclusión, pero estaba posponiendo hacer una nueva escritura completa. Sin embargo, finalmente llegué a hacer esto el viernes y ahora tengo un sistema mucho mejor –

1

Puede tener un actor de programación que tenga una lista de actores programados, y usa Actor.receiveWithin() para despertarse cada segundo y enviar mensajes a los actores que están listos para ser ejecutados. El actor de programación también podría manejar la cancelación. Otra opción es permitir que cada actor maneje su propia programación directamente con receiveWithin(), en lugar de centralizar la programación.

Existe un debate sobre este tema en la publicación del blog Simple cron like scheduler in Scala.