JVM Languages

JVM Concurrency and Actors with GPars

By Vaclav Pech, April 25, 2011

The GPars project makes concurrency easily accessible and safe to use on the JVM

This article is the first in a new monthly series, which presents and examines an open-source project of interest to serious developers. We begin this series with GPars, a concurrency framework for the JVM that greatly facilitates actor-based programming. — Andrew Binstock

The GPars project makes concurrency easily accessible and safe to use on the JVM. In this article. I'll focus on the actor model part of GPars. We'll experiment with the various types of actors that GPars provides and see their typical usages. All the project‘s functionality is available from Java and from Groovy, with which GPars is most often associated.

Introduction to Actors

The concept of actors as an approach to organizing concurrent activities has recently gained new popularity (thanks to the Scala, Erlang, and other programming languages). Actors provide a programming model that gives stronger guarantees about concurrent code when compared with the traditional shared-memory-based abstraction. Actors are essentially well encapsulated active objects, which can only communicate by sending one another immutable messages asynchronously. Whatever state an actor holds internally, it cannot be accessed from outside the actor except by sending a message to the actor and receiving its reply.

Because actors handle incoming messages asynchronously, they themselves need to be active. One way to make an object active is to dedicate a system thread to it. With actors, however, you frequently need to scale beyond the number of threads available on the system. That's why actor implementations usually share threads among actors. If an actor has no work to do, it doesn't consume system threads.

Actors guarantee that there's never more than one thread at a time processing the messages of each actor. The actor's state can thus be modified safely from within its body without any other extra (synchronization or locking) effort. The actor's own code is implicitly thread-safe.

Actors in GPars

GPars is an open-source project that provides a Java implementation of actors, with a convenient API for direct use either from Groovy or Java. Actors perform three specific operations — they send messages, receive messages, and create new actors. Although not enforced by GPars, messages should be immutable or at least follow a hands-off policy in which the sender never touches the messages after the message has been sent off. This code shows an example of actors at work.

In the Java examples in the preceding code, you find all the fundamental actor operations. Actors are being created, started, and stopped. Messages are being sent, received, and replied to asynchronously. The message themselves are immutable values. Let's go through these in detail now.

Creating Actors

Actors can be created either by instantiating the appropriate class (see main()) or using appropriate factory methods. The former approach is preferred when instantiating actors in Java, while the latter approach feels more Groovy-like.

Sending messages

Messages can be sent to actors using the send() method. Alternatively, the << operator or the implicit call() method can be used, when calling the actor from Groovy.

Types of Actors

In general, you can find two types of actors in the wild: those that hold implicit state, and those that don't. GPars gives you both options. Stateless actors, represented in GPars by the DynamicDispatchActor and the ReactiveActor classes, do not keep track of what messages have arrived previously. This is the type of actor presented in the examples so far. You can think of these as flat message handlers: They process messages as they arrive. Any state-based behavior has to be implemented by the programmer.

Stateful actors, on the other hand, represented in GPars by the DefaultActor class, allow the actor to handle the implicit state directly. After receiving a message, the actor moves into a new state with different set of handlers to handle future messages.

A stateful actor doesn't provide independent message handlers. Instead, a stateful actor defines a body — a block of code to execute when the actor starts. Inside the body, the actor may check for messages any time by calling the react method. Depending on the actual message contents, the actor executes different actions.

Stateless Actors

DynamicDispatchActor repeatedly scans for received messages and dispatches them to one of the onMessage() methods defined in the actor. The DynamicDispatchActor leverages the Groovy dynamic method dispatch mechanism under the covers. Even if the class is implemented in Java, the messages are dispatched dynamically to the right message handler:

The ReactiveActor class allows for more event-driven-like approach. You can also view it as an asynchronous function of a sort. When a reactive actor receives a message, the actor's body is run with the message as a parameter. The result of this is then returned in reply.

As you can see, you create new actors with the actor() factory method passing in the actor's body as a closure parameter. Once started, actors run their body top to bottom, reading messages from their mail-boxes along the way. Inside the actor's body you can use loop() to iterate, react() to receive messages, and reply() to send a reply to the currently processed message.

Notice the implicit state transitions of the actor. The first message that arrives is handled by a different handler than the second message in the sequence.

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!