2010-12-04 16 views
5

Supongamos que tengo un actor que tiene un solo campo. 99 de cada 100 mensajes a un actor leen el valor, y el 100º actualiza el valor. En este caso, me gustaría procesar las lecturas en paralelo. En otras palabras, ¿cómo puedo lograr el rendimiento de los bloqueos de lectura/escritura con actores? ¿Es esto práctico con los actores estándar de Scala o Akka? O me estoy perdiendo el punto de actores :)Actores: Cómo manejar eficientemente los datos de lectura mayoritaria

Actualización: fijo lenguaje confuso, lo siento

+1

¿No son todos los mensajes para los actores solo de lectura (inmutables)? El actor recibe un mensaje y procesa algo según el mensaje. Si es necesario, envía un mensaje a otro actor como parte del procesamiento. –

+0

Sí, los mensajes son inmutables.Imagine el ejemplo común de un contador/incrementador como actor: me pregunto si leer el valor actual puede ser no bloqueante para otras operaciones de lectura. –

Respuesta

6

Estás muy posiblemente perdiendo el punto de actores. Supongo que quieres un actor al que le envíes una consulta y luego devuelve una respuesta. Hay una gran cantidad de maquinaria involucrada en enviar un mensaje a un actor, procesarlo y enviar una respuesta. La generación real del mensaje de respuesta se creará como una tarea y se enviará a un grupo de subprocesos. Entre la cola de mensajes y el grupo de subprocesos hay varios lugares que requieren bloqueos o, en el mejor de los casos, operaciones de CAS. Por lo general, el punto es que el actor hará algo de trabajo en un hilo separado basado en ese mensaje.

Si solo desea leer y rara vez escribir datos (como incrementar un contador o acceder a un valor en un mapa) será mucho mejor que utilice una clase apropiada de java.util.concurrent.

3

Supongo que quiere decir que todos los mensajes son inmutables y que casi todos los mensajes no cambian el estado del actor. En este caso, los actores probablemente no sean la mejor opción de diseño. Los actores te permiten administrar cualquier estado mutable como si estuvieras manejando un código de un solo hilo.

Efectivamente, cada actor tiene un buzón al que se envían los mensajes y luego se los procesa de a uno por vez. En su escenario, esto sería bastante derrochador. Como se sugirió, usar algo de java.util.concurrent sería lo más efectivo.

2

Los actores están diseñados para procesar los mensajes en serie. Esto los hace más fáciles de razonar: obtienes un mensaje a la vez, de modo que cualquier variable del actor (siempre que no sean mutados por nadie) se puede modificar sin pensar en la concurrencia. ¿Es este el método más eficiente? ¡Absolutamente no! Pero código algo ineficiente que funciona correctamente es casi siempre mejor que código altamente eficiente que se rompe.

Lo que está pidiendo es exactamente lo contrario: quiere pensar explícitamente sobre la concurrencia ("Sé que el 99% de los accesos se leerán y pueden ocurrir en paralelo") para ganar velocidad de procesamiento. En este caso, probablemente desee utilizar java.util.concurrent.locks.ReentrantReadWriteLock para controlar directamente el acceso a una variable mutable (si el tipo de acceso encontrado en java.util.concurrent.atomic._ no le funciona). Solo recuerde que ahora ha asumido la carga de obtener el bloqueo correcto, y tenga el cuidado apropiado.

Cuestiones relacionadas