Even with the introduction of concurrency updates in Java 6 and Java 7, the Java language still does not make parallel programming particularly easy. Java threads, synchronized code blocks, wait/notify, and java.util.concurrent packages all have their own locations, but Java developers are relying on technology pioneered in other languages in the face of capacity pressures on multi-core systems. The actor model is a technology that has been implemented in Erlang, Groovy, and Scala. This article brings a μjavaactors library for developers who want to experience actor but continue to write Java code.
The Μjavaactors Library is a compact library for implementing actor based systems on the Java platform (μ represents the Greek letter mμ, meaning "miniature"). In this article, I use μjavaactors to explore how actor works in common design patterns such as Producer/consumer and Map/reduce.
You can download the source code for the Μjavaactors library at any time.
Actor concurrency on the Java platform
What does the name mean? Actor with any other name is also applicable!
Based on actor system, the parallel processing is easier to encode by implementing a message passing mode. In this mode, each actor in the system can receive messages, perform the actions represented by the message, and then send messages to other actor (including themselves) to perform complex sequences of operations. All messages between actor are asynchronous, which means that the sender will continue processing before any reply is received. As a result, a actor may be stuck in an infinite loop of receiving and processing messages for life.
When multiple actor are used, independent activities can easily be allocated to multiple threads that can execute messages concurrently (and then to multiple processors). Generally, each actor processes messages on a separate thread. Some actor systems statically assign threads to actor, while other systems, such as the systems described in this article, dynamically assign them.
Μjavaactors Introduction
Μjavaactors is a simple Java implementation of the actor system. With only 1,200 lines of code, Μjavaactors is very small, but very powerful. In the following exercises, you will learn how to use Μjavaactors to dynamically create and manage actor, passing messages to them.
Μjavaactors is built around 3 core interfaces:
Messages are messages that are sent between actor. The message is a container of 3 (optional) values and some behaviors:
Source is the sending actor.
Subject is a string (also known as a command) that defines the meaning of a message.
Data is any parameter of a message, usually a map, list, or array. Parameters can be data that you want to process and/or other actor to interact with.
Subjectmatches () checks whether the message topic matches a string or regular expression.
The default message class for the Μjavaactors package is defaultmessage.
Actormanager is a actor manager. It is responsible for assigning a thread to the actor (and thus allocating the processor) to process the message. Actormanager has the following key behaviors or characteristics:
Createactor () Creates a actor and associates it with this manager.
Startactor () starts a actor.
Detachactor () stops a actor and disconnects it from this manager.
Send ()/broadcast () sends a message to a actor, a group of actor, any actor in a category, or all actor.
In most programs, there is only one actormanager, but you can also have multiple actormanager if you want to manage multiple lines of threads/or actor pools. The default implementation of this interface is Defaultactormanager.
Actor is an execution unit that processes a single message at a time. Actor has the following key behaviors or characteristics:
Each actor has a name that must be unique within each actormanager.
Each actor belongs to a category category is a way to send a message to a member of a group of actor. A actor can only belong to one category at a time.
The system calls receive () as long as Actormanager can provide a thread that executes the actor. To maintain maximum efficiency, actor should quickly process messages rather than entering a lengthy waiting state (such as waiting for human input).
Willreceive () allows actor to filter potential message topics.
Peek () allows the actor and other actor to see if a pending message exists (or perhaps to select a theme).
Remove () allows the actor and other actor to delete or cancel any messages that have not yet been processed.
Getmessagecount () allows the actor and other actor to get the number of pending messages.
Getmaxmessagecount () allows actor to limit the number of pending messages that are supported, and this method can be used to prevent uncontrolled delivery.
Most programs have many actor, and these actor often have different types. Actor can be created at program startup or created (and destroyed) when the program executes. The actor package in this article contains an abstract class called Abstractactor, actor implementation based on that class.
Figure 1 shows the relationship between the actor. Each actor can send messages to other actor. These messages are saved in a message queue (also known as a mailbox; Conceptually, each actor has a queue, and when Actormanager sees that a thread can be used to process the message, it is removed from the queue and routed to the actor running under the thread to process the message.)
Figure 1. The relationship between actor
Parallel execution function of μjavaactors
Now you are ready to start using the Μjavaactors implementation in parallel. First you create a set of actor. These are simple actor, as they do only delay a small amount of time and send messages to other actor. The effect is to create a message storm, and you'll first see how to create actor, and then see how to incrementally assign them to process messages.