Learn how Groovy's concurrency library leverages the popular concurrency model and makes it accessible on the Java platform
In the concurrency age, chips with 4, 6, and 16 processor cores become commonplace, and in the near future we will see chips with hundreds or even thousands of cores. This ability to handle is a huge possibility, but it also poses challenges for software developers. The need to maximize the use of these shiny new cores drives a focus on concurrency, state management, and programming languages built for both.
JVM languages such as Groovy, Scala, and Clojure meet these requirements. These three are newer languages that run on top of the highly optimized JVM and can use the powerful Java concurrency Library that is new in Java 1.5. Although each language uses different methods based on its principles, they all actively support concurrent programming.
In this article, we'll use Gpars, a Groovy-based concurrency library, to examine the model to address concurrency issues, such as background processing, parallel processing, state management, and thread coordination.
Why do you choose Groovy? Why Choose Gpars?
Groovy is a dynamic language running on top of the JVM. Based on the Java language, Groovy removes a large number of formal syntax from Java code and adds useful features from other programming languages. One of the great features of groovy is that it allows programmers to easily create a DSL based on groovy.
Gpars or Groovy Parallel Systems is a groovy concurrency library that captures concurrency and coordination models as DSLs. Gpars's idea derives from some of the most popular concurrency and coordination models in other languages, including:
Executors and Fork/join from the Java language
Actors from Erlang and Scala
Agents from Clojure.
Data flow variables from Oz
The combination of Groovy and Gpars becomes the ideal choice for demonstrating a variety of concurrency methods. Even Java developers who are unfamiliar with groovy can easily focus on the discussion because Groovy's syntax is based on the Java language. The examples in this article are based on Groovy 1.7 and Gpars 0.10.
Background and parallel processing
A common performance challenge is the need to wait for I/O. I/O may involve reading data from a disk, a Web service, or even a user. When a thread is blocked while waiting for I/O, it is useful to detach the waiting thread from the original execution thread, which will enable it to continue working. Since this wait is happening in the background, we call this technology background processing.
For example, suppose we need a program that invokes the Twitter API to find the latest tweets for several JVM languages and print them out. Groovy can easily write such a program using Java library twitter4j, as shown in Listing 1:
Listing 1. Serial read tweets (Langtweets.groovy)
import twitter4j.Twitter
import twitter4j.Query
@Grab(group='net.homeip.yusuke', module='twitter4j', version='2.0.10')
def recentTweets(api, queryStr) {
query = new Query(queryStr)
query.rpp = 5 // tweets to return
query.lang = "en" // language
tweets = api.search(query).tweets
threadName = Thread.currentThread().name
tweets.collect {
"[${threadName}-${queryStr}] @${it.fromUser}: ${it.text}"
}
}
def api = new Twitter()
['#erlang','#scala','#clojure'].each {
tweets = recentTweets(api, it)
tweets.each {
println "${it}"
}
}