Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Learning Concurrent Programming in Scala
Learning Concurrent Programming in Scala

Learning Concurrent Programming in Scala: Dive into the Scala framework with this programming guide, created to help you learn Scala and to build intricate, modern, scalable concurrent applications

eBook
€8.99 €29.99
Paperback
€36.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Learning Concurrent Programming in Scala

Chapter 1. Introduction

 

"For over a decade prophets have voiced the contention that the organization of a single computer has reached its limits and that truly significant advances can be made only by interconnection of a multiplicity of computers."

 
 --Gene Amdahl, 1967

Although the discipline of concurrent programming has a long history, it gained a lot of traction in recent years with the arrival of multicore processors. The recent development in computer hardware not only revived some classical concurrency techniques, but also started a major paradigm shift in concurrent programming. At a time, when concurrency is becoming so important, an understanding of concurrent programming is an essential skill for every software developer.

This chapter explains the basics of concurrent computing and presents some Scala preliminaries required for this book. Specifically, it does the following:

  • Shows a brief overview of concurrent programming
  • Studies the advantages of using Scala when it comes to concurrency
  • Covers the Scala preliminaries required for reading this book

We will start by examining what concurrent programming is and why it is important.

Concurrent programming

In concurrent programming, we express a program as a set of concurrent computations that execute during overlapping time intervals and coordinate in some way. Implementing a concurrent program that functions correctly is usually much harder than implementing a sequential one. All the pitfalls present in sequential programming lurk in every concurrent program, but there are many other things that can go wrong, as we will learn in this book. A natural question arises: why bother? Can't we just keep writing sequential programs?

Concurrent programming has multiple advantages. First, increased concurrency can improve program performance. Instead of executing the entire program on a single processor, different subcomputations can be performed on separate processors making the program run faster. With the spread of multicore processors, this is the primary reason why concurrent programming is nowadays getting so much attention.

Then, a concurrent programming model can result in faster I/O operations. A purely sequential program must periodically poll I/O to check if there is any data input available from the keyboard, the network interface, or some other device. A concurrent program, on the other hand, can react to I/O requests immediately. For I/O-intensive operations, this results in improved throughput, and is one of the reasons why concurrent programming support existed in programming languages even before the appearance of multiprocessors. Thus, concurrency can ensure the improved responsiveness of a program that interacts with the environment.

Finally, concurrency can simplify the implementation and maintainability of computer programs. Some programs can be represented more concisely using concurrency. It can be more convenient to divide the program into smaller, independent computations than to incorporate everything into one large program. User interfaces, web servers, and game engines are typical examples of such systems.

In this book, we adopt the convention that concurrent programs communicate through the use of shared memory, and execute on a single computer. By contrast, a computer program that executes on multiple computers, each with its own memory, is called a distributed program, and the discipline of writing such programs is called distributed programming. Typically, a distributed program must assume that each of the computers can fail at any point, and provide some safety guarantees if this happens. We will mostly focus on concurrent programs, but we will also look at examples of distributed programs.

A brief overview of traditional concurrency

In a computer system, concurrency can manifest itself in the computer hardware, at the operating system level, or at the programming language level. We will focus mainly on programming language-level concurrency.

Coordination of multiple executions in a concurrent system is called synchronization, and it is a key part in successfully implementing concurrency. Synchronization includes mechanisms used to order concurrent executions in time. Furthermore, synchronization specifies how concurrent executions communicate, that is, how they exchange information. In concurrent programs, different executions interact by modifying the shared memory subsystem of the computer. This type of synchronization is called shared memory communication. In distributed programs, executions interact by exchanging messages, so this type of synchronization is called message-passing communication.

At the lowest level, concurrent executions are represented by entities called processes and threads, covered in Chapter 2, Concurrency on the JVM and the Java Memory Model. Processes and threads traditionally use entities such as locks and monitors to order parts of their execution. Establishing an order between the threads ensures that the memory modifications done by one thread are visible to a thread that executes later.

Often, expressing concurrent programs using threads and locks is cumbersome. More complex concurrent facilities have been developed to address this such as communication channels, concurrent collections, barriers, countdown latches, and thread pools. These facilities are designed to more easily express specific concurrent programming patterns, and some of them are covered in Chapter 3, Traditional Building Blocks of Concurrency.

Traditional concurrency is relatively low level and prone to various kinds of errors, such as deadlocks, starvations, data races, and race conditions. You will rarely use low-level concurrency primitives when writing concurrent Scala programs. Still, a basic knowledge of low-level concurrent programming will prove invaluable in understanding high-level concurrency concepts later.

Modern concurrency paradigms

Modern concurrency paradigms are more advanced than traditional approaches to concurrency. Here, the crucial difference lies in the fact that a high-level concurrency framework expresses which goal to achieve, rather than how to achieve that goal.

In practice, the difference between low-level and high-level concurrency is less clear, and different concurrency frameworks form a continuum rather than two distinct groups. Still, recent developments in concurrent programming show a bias towards declarative and functional programming styles.

As we will see in Chapter 2, Concurrency on the JVM and the Java Memory Model, computing a value concurrently requires creating a thread with a custom run method, invoking the start method, waiting until the thread completes, and then inspecting specific memory locations to read the result. Here, what we really want to say is "compute some value concurrently, and inform me when you are done." Furthermore, we would like to treat the result of the concurrent computation as if we already have it, rather than having to wait for it, and then reading it from the memory. Asynchronous programming using futures is a paradigm designed to specifically support these kinds of statements, as we will learn in Chapter 4, Asynchronous Programming with Futures and Promises. Similarly, reactive programming using event streams aims to declaratively express concurrent computations that produce many values, as we will see in Chapter 6, Concurrent Programming with Reactive Extensions.

The declarative programming style is increasingly common in sequential programming too. Languages such as Python, Haskell, Ruby, and Scala express operations on their collections in terms of functional operators, and allow statements such as "filter all negative integers from this collection." This statement expresses a goal rather than the underlying implementation, so it is easy to parallelize such an operation behind the scene. Chapter 5, Data-Parallel Collections, describes the data-parallel collections framework available in Scala, which is designed to seamlessly accelerate collection operations using multiple processors.

Another trend seen in high-level concurrency frameworks is specialization towards specific tasks. Software transactional memory technology is specifically designed to express memory transactions, and does not deal with how to start concurrent executions at all. A memory transaction is a sequence of memory operations that appear as if they either execute all at once or do not execute at all. The advantage of using memory transactions is that this avoids a lot of errors typically associated with low-level concurrency. Chapter 7, Software Transactional Memory, explains software transactional memory in detail.

Finally, some high-level concurrency frameworks aim to transparently provide distributed programming support as well. This is especially true for data-parallel frameworks and message passing concurrency frameworks, such as the actors described in Chapter 8, Actors.

The advantages of Scala

Although Scala is still a language on the rise that has yet to receive the wide-scale adoption of a language such as Java, its support for concurrent programming is rich and powerful. Concurrency frameworks for nearly all the different styles of concurrent programming exist in the Scala ecosystem, and are being actively developed. Throughout its development, Scala has pushed the boundaries when it comes to providing modern, high-level application programming interfaces or APIs for concurrent programming. There are many reasons for this.

The primary reason that so many modern concurrency frameworks have found their way into Scala is its inherent syntactic flexibility. Thanks to features such as first-class functions, by-name parameters, type inference, and pattern matching explained in the following sections, it is possible to define APIs that look as if they are built-in language features.

Such APIs emulate various programming models as embedded domain-specific languages, with Scala serving as a host language: actors, software transactional memory, and futures are examples of APIs that look like they are basic language features, when they are in fact implemented as libraries. On one hand, Scala avoids the need for developing a new language for each new concurrent programming model, and serves as a rich nesting ground for modern concurrency frameworks. On the other hand, lifting the syntactic burden present in many other languages attracts more users.

The second reason Scala has pushed ahead lies in the fact that it is a safe language. Automatic garbage collection, automatic bound checks, and the lack of pointer arithmetic help to avoid problems such as memory leaks, buffer overflows, and other memory errors. Similarly, static type safety eliminates a lot of programming errors at an early stage. When it comes to concurrent programming, which is in itself prone to various kinds of concurrency errors, having one less thing to worry about can make a world of difference.

The third important reason is interoperability. Scala programs are compiled into Java bytecode, so the resulting executable code runs on top of the Java Virtual Machine (JVM). This means that Scala programs can seamlessly use existing Java libraries, and interact with Java's rich ecosystem. Often, transitioning to a different language is a painful process. In the case of Scala, a transition from a language such as Java can proceed gradually and is much easier. This is one of the reasons for its growing adoption, and also a reason why some Java-compatible frameworks choose Scala as their implementation language.

Importantly, the fact that Scala runs on the JVM implies that Scala programs are portable across a range of different platforms. Not only that, but the JVM has well-defined threading and memory models, which are guaranteed to work in the same way on different computers. While portability is important for the consistent semantics of sequential programs, it is even more important when it comes to concurrent computing.

Having seen some of Scala's advantages for concurrent programming, we are now ready to study the language features relevant for this book.

Preliminaries

This book assumes basic familiarity with sequential programming. While we advise the readers to get acquainted with the Scala programming language, an understanding of a similar language, such as Java or C#, should be sufficient for reading this book. A basic familiarity with concepts in object-oriented programming, such as classes, objects, and interfaces is helpful. Similarly, a basic understanding of functional programming principles such as first-class functions, purity, and type-polymorphism are beneficial in understanding this book, but are not a strict prerequisite.

Execution of a Scala program

To better understand the execution model of Scala programs, let's consider a simple program that uses the square method to compute the square value of the number five, and then prints the result to the standard output:

object SquareOf5 extends App {
  def square(x: Int): Int = x * x
  val s = square(5)
  println(s"Result: $s")
}

We can run this program using the Simple Build Tool (SBT), as described in the Preface. When a Scala program runs, the JVM runtime allocates the memory required for the program. Here, we consider two important memory regions: the call stack and the object heap. The call stack is a region of memory in which the program stores information about the local variables and parameters of the currently executed methods. The object heap is a region of memory in which the objects are allocated by the program. To understand the difference between the two regions, we consider a simplified scenario of this program's execution.

First, in figure 1, the program allocates an entry to the call stack for the local variable s. Then, it calls the square method in figure 2 to compute the value for the local variable s. The program places the value 5 on the call stack, which serves as the value for the x parameter. It also reserves a stack entry for the return value of the method. At this point, the program can execute the square method, so it multiplies the x parameter by itself, and places the return value 25 on the stack in figure 3. This is shown in the first row in the following illustration:

Execution of a Scala program

After the square method returns the result, the result 25 is copied into the stack entry for the local variable s, as shown in figure 4. Now, the program must create the string for the println statement. In Scala, strings are represented as object instances of the String class, so the program allocates a new String object to the object heap, as illustrated in figure 5. Finally, in figure 6, the program stores the reference to the newly allocated object into the stack entry x, and calls the println method.

Although this demonstration is greatly simplified, it shows the basic execution model for Scala programs. In Chapter 2, Concurrency on the JVM and the Java Memory Model, we will learn that each thread of execution maintains a separate call stack, and that threads mainly communicate by modifying the object heap. We will learn that the disparity between the state of the heap and the local call stack is frequently responsible for certain kinds of error in concurrent programs.

Having seen an example of how Scala programs are typically executed, we now proceed to an overview of Scala features that are essential to understand the contents of this book.

A Scala primer

In this section, we present a short overview of the Scala programming language features that are used in the examples in this book. This is a quick and cursory glance through the basics of Scala. Note that this section is not meant to be a complete introduction to Scala. This is to remind you about some of the language's features, and contrast them with similar languages that might be familiar to you. If you would like to learn more about Scala, refer to some of the books referred in the summary of this chapter.

A Printer class, which takes a greeting parameter, and has two methods named printMessage and printNumber, is declared as follows:

class Printer(val greeting: String) {
  def printMessage(): Unit = println(greeting + "!")
  def printNumber(x: Int): Unit = {
    println("Number: " + x)
  }
}

In the preceding code, the printMessage method does not take any arguments, and contains a single println statement. The printNumber method takes a single argument x of the Int type. Neither method returns a value, which is denoted by the Unit type. The Unit type can be omitted, in which case it is inferred automatically by the Scala compiler.

We instantiate the class and call its methods as follows:

val printy = new Printer("Hi")
printy.printMessage()
printy.printNumber(5)

Scala allows the declaration of singleton objects. This is like declaring a class and instantiating its single instance at the same time. We saw the SquareOf5 singleton object earlier, which was used to declare a simple Scala program. The following singleton object, named Test, declares a single Pi field and initializes it with the value 3.14:

object Test {
  val Pi = 3.14
}

Where classes in similar languages extend entities that are called interfaces, Scala classes can extend traits. Scala's traits allow declaring both concrete fields and method implementations. In the following example, we declare the Logging trait that outputs custom error and warning messages using the abstract log method, and then mix the trait into the PrintLogging class:

trait Logging {
  def log(s: String): Unit
  def warn(s: String) = log("WARN: " + s)
  def error(s: String) = log("ERROR: " + s)
}
class PrintLogging extends Logging {
  def log(s: String) = println(s)
}

Classes can have type parameters. The following generic Pair class takes two type parameters P and Q, which determine the types of its arguments, named first and second:

class Pair[P, Q](val first: P, val second: Q)

Scala has support for first-class function objects, also called lambdas. In the following code snippet, we declare a twice lambda, which multiplies its argument by two:

val twice: Int => Int = (x: Int) => x * 2

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

In the preceding code, the (x: Int) part is the argument to the lambda, and x * 2 is its body. The => symbol must be placed between the arguments and the body of the lambda. The same => symbol is also used to express the type of the lambda, which is Int => Int. In the preceding example, we can omit the type annotation Int => Int, and the compiler will infer the type of the twice lambda automatically, as shown in the following code:

val twice = (x: Int) => x * 2

Alternatively, we can omit the type annotation in the lambda declaration and arrive at a more convenient syntax, as follows:

val twice: Int => Int = x => x * 2

Finally, whenever the argument to the lambda appears only once in the body of the lambda, Scala allows a more convenient syntax, as follows:

val twice: Int => Int = _ * 2

First-class functions allow manipulating blocks of code as if they were first-class values. They allow a more lightweight and concise syntax. In the following example, we use by-name parameters to declare a runTwice method, which runs the specified block of code body twice:

def runTwice(body: =>Unit) = {
  body
  body
}

A by-name parameter is formed by putting the => annotation before the type. Whenever the runTwice method references the body argument, the expression is re-evaluated, as shown in the following snippet:

runTwice { // this will print Hello twice
  println("Hello")
}

Scala for expressions are a convenient way to traverse and transform collections. The following for loop prints the numbers in the range from 0 until 10, where 10 is not included in the range:

for (i <- 0 until 10) println(i)

In the preceding code, the range is created with the expression 0 until 10, which is equivalent to the expression 0.until(10), which calls the method until on the value 0. In Scala, the dot notation can sometimes be dropped when invoking methods on objects.

Every for loop is equivalent to a foreach call. The preceding for loop is translated by the Scala compiler to the following expression:

(0 until 10).foreach(i => println(i))

For-comprehensions are used to transform data. The following for-comprehension transforms all the numbers from 0 until 10 by multiplying them by -1:

val negatives = for (i <- 0 until 10) yield -i

The negatives value contains negative numbers from 0 until -10. This for-comprehension is equivalent to the following map call:

val negatives = (0 until 10).map(i => -1 * i)

It is also possible to transform data from multiple inputs. The following for-comprehension creates all pairs of integers between zero and four:

val pairs = for (x <- 0 until 4; y <- 0 until 4) yield (x, y)

The preceding for-comprehension is equivalent to the following expression:

val pairs = (0 until 4).flatMap(x => (0 until 4).map(y => (x, y)))

We can nest an arbitrary number of generator expressions in a for-comprehension. The Scala compiler will transform them into a sequence of nested flatMap calls, followed by a map call at the deepest level.

Commonly used Scala collections include sequences, denoted by the Seq[T] type; maps, denoted by the Map[T] type; and sets, denoted by the Set[T] type. In the following code, we create a sequence of strings:

val messages: Seq[String] = Seq("Hello", "World.", "!")

Throughout this book, we rely heavily on the string interpolation feature. Normally, Scala strings are formed with double quotation marks. Interpolated strings are preceded with an s character, and can contain $ symbols with arbitrary identifiers resolved from the enclosing scope, as shown in the following example:

val magic = 7
val myMagicNumber = s"My magic number is $magic"

Pattern matching is another important Scala feature. For readers with Java, C#, or C background, it suffices to say that Scala's match statement is like the switch statement on steroids. The match statement can decompose arbitrary datatypes, and allows you to express different cases in the program concisely.

In the following example, we declare a Map collection, named successors, used to map integers to their immediate successors. We then call the get method to obtain the successor of the number five. The get method returns an object with the Option[Int] type, which may either be implemented with the Some class, indicating that the number five exists in the map, or the None class, indicating that the number five is not a key in the map. Pattern matching on the Option object allows proceeding casewise, as shown in the following code snippet:

val successors = Map(1 -> 2, 2 -> 3, 3 -> 4)
successors.get(5) match {
  case Some(n) => println(s"Successor is: $n")
  case None    => println("Could not find successor.")
}

In Scala, most operators can be overloaded. Operator overloading is no different from declaring a method. In the following code snippet, we declare a Position class with a + operator:

class Position(val x: Int, val y: Int) {
  def +(that: Position) = new Position(x + that.x, y + that.y)
}

Finally, Scala allows defining package objects to store top-level method and value definitions for a given package. In the following code snippet, we declare the package object for the org.learningconcurrency package. We implement the top-level log method, which outputs a given string and the current thread name:

package org
package object learningconcurrency {
  def log(msg: String): Unit =
    println(s"${Thread.currentThread.getName}: $msg")
}

We will use the log method in the examples throughout this book to trace how the concurrent programs are executed.

This concludes our quick overview of important Scala features. If you would like to obtain a deeper knowledge about any of these language constructs, we suggest that you check out one of the introductory books on sequential programming in Scala.

Summary

In this chapter, we studied what concurrent programming is and why Scala is a good language for concurrency. We gave a brief overview of what you will learn in this book, and how the book is organized. Finally, we stated some Scala preliminaries necessary for understanding the various concurrency topics in the subsequent chapters. If you would like to learn more about sequential Scala programming, we suggest that you read the book Programming in Scala, Martin Odersky, Lex Spoon, and Bill Venners, Artima Inc.

In the next chapter, we will start with the fundamentals of concurrent programming on the JVM. We will introduce the basic concepts in concurrent programming, present the low-level concurrency utilities available on the JVM, and learn about the Java Memory Model.

Exercises

The following exercises are designed to test your knowledge of the Scala programming language. They cover the content presented in this chapter, along with some additional Scala features. The last two exercises contrast the difference between concurrent and distributed programming, as defined in this chapter. You should solve them by sketching out a pseudocode solution, rather than a complete Scala program.

  1. Implement a compose method with the following signature:
    def compose[A, B, C](g: B => C, f: A => B): A => C = ???

    This method must return a function h, which is the composition of the functions f and g.

  2. Implement a fuse method with the following signature:
    def fuse[A, B](a: Option[A], b: Option[B]): Option[(A, B)] = ???

    The resulting Option object should contain a tuple of values from the Option objects a and b, given that both a and b are non-empty. Use for-comprehensions.

  3. Implement a check method, which takes a set of values of the type T and a function of the type T => Boolean:
    def check[T](xs: Seq[T])(pred: T => Boolean): Boolean = ???

    The method must return true if and only if the pred function returns true for all the values in xs without throwing an exception. Use the check method as follows:

    check(0 until 10)(40 / _ > 0)

    Tip

    The check method has a curried definition: instead of just one parameter list, it has two of them. Curried definitions allow a nicer syntax when calling the function, but are otherwise semantically equivalent to single-parameter list definitions.

  4. Modify the Pair class from this chapter so that it can be used in a pattern match.

    Tip

    If you haven't already, familiarize yourself with pattern matching in Scala.

  5. Implement a permutations function, which, given a string, returns a sequence of strings that are lexicographic permutations of the input string:
    def permutations(x: String): Seq[String]
  6. Consider yourself and three of your colleagues working in an office divided into cubicles. You cannot see each other, and you are not allowed to verbally communicate, as that might disturb other workers. Instead, you can throw pieces of paper with short messages at each other. Since you are confined in a cubicle, neither of you can tell if the message has reached its destination. At any point, you or one of your colleagues may be called to the boss's office and kept there indefinitely. Design an algorithm in which you and your colleagues can decide when to meet at the local bar. With the exception of the one among you who was called to the boss's office, all of you have to decide on the same time. What if some of the paper pieces can arbitrarily miss the target cubicle?
  7. Imagine that in the previous exercise, you and your colleagues also have a whiteboard in the hall next to the office. Each one of you can occasionally pass through the hall and write something on the whiteboard, but there is no guarantee that either of you will be in the hall at the same time.

    Solve the problem from the previous exercise, this time using the whiteboard.

Left arrow icon Right arrow icon

Description

This book is a must-have tutorial for software developers aiming to write concurrent programs in Scala, or broaden their existing knowledge of concurrency. This book is intended for Scala programmers that have no prior knowledge about concurrent programming, as well as those seeking to broaden their existing knowledge about concurrency. Basic knowledge of the Scala programming language will be helpful. Readers with a solid knowledge in another programming language, such as Java, should find this book easily accessible.

What you will learn

  • Get to grips with the fundamentals of concurrent programming on modern multiprocessor systems, with a particular focus on the JVM concurrency model
  • Build highperformance concurrent systems from simple, lowlevel concurrency primitives
  • Express asynchrony in concurrent computations with futures and promises
  • Seamlessly accelerate sequential programs by using dataparallel collections
  • Implement reactive and eventbased programs declaratively with Rxstyle event streams
  • Design safe, scalable, and easytocomprehend inmemory transactional data models
  • Transparently create distributed applications that scale across multiple machines
  • Choose the correct concurrency abstraction and integrate different concurrency frameworks together in large applications
Estimated delivery fee Deliver to Malta

Premium delivery 7 - 10 business days

€32.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Nov 28, 2014
Length: 366 pages
Edition : 1st
Language : English
ISBN-13 : 9781783281411
Category :
Languages :
Concepts :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Malta

Premium delivery 7 - 10 business days

€32.95
(Includes tracking information)

Product Details

Publication date : Nov 28, 2014
Length: 366 pages
Edition : 1st
Language : English
ISBN-13 : 9781783281411
Category :
Languages :
Concepts :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 124.97
Scala for Java Developers
€37.99
Scala for Machine Learning
€49.99
Learning Concurrent Programming in Scala
€36.99
Total 124.97 Stars icon
Banner background image

Table of Contents

10 Chapters
1. Introduction Chevron down icon Chevron up icon
2. Concurrency on the JVM and the Java Memory Model Chevron down icon Chevron up icon
3. Traditional Building Blocks of Concurrency Chevron down icon Chevron up icon
4. Asynchronous Programming with Futures and Promises Chevron down icon Chevron up icon
5. Data-Parallel Collections Chevron down icon Chevron up icon
6. Concurrent Programming with Reactive Extensions Chevron down icon Chevron up icon
7. Software Transactional Memory Chevron down icon Chevron up icon
8. Actors Chevron down icon Chevron up icon
9. Concurrency in Practice Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.7
(10 Ratings)
5 star 70%
4 star 30%
3 star 0%
2 star 0%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




Thomas Ulrich Mar 21, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Very good, in-depth study of JVM concurrency intrinsics followed by Scala concurrency frameworks. In addition to the well-written study, each topic includes short, pragmatic, runnable example idioms demonstrating the current topic. The book concludes with a more comprehensive example comprising key concurrency libraries previously covered in book. Very well done! Highly recommended.
Amazon Verified review Amazon
MI Mar 05, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
It starts from the basics and goes quite deep in several topics regarding JVM concurrency. One of the greatest strength of Scala is its concurrency abstractions and this book does a good job at explaining them.
Amazon Verified review Amazon
David De Jun 25, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Best book on concurrency, period.
Amazon Verified review Amazon
Robert Dawson Jan 16, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I really enjoyed reading this book. The Scala community needed a manual such as this for a while now. Before this book, documentation on concurrent programming in Scala consisted mostly of online SIP documents, tutorials scattered across multiple websites, Stackoverflow answers and random blog posts. This results in scattered, incomplete and often convoluted information about Scala concurrency. Learning Concurrent Programming in Scala constitutes a readable and authoritative manual on using these concurrency libraries, with everything needed to get you started in one place. Although I recommend getting acquainted with sequential programming in Scala first, people who want to write concurrent programs in Scala should definitely read this book. That does not mean that the book is valuable only for Scala programmers - as someone with 11 years of industry experience in Java, I can honestly say that the concurrency novelties described in this book will be interesting to programmers coming from backgrounds different than Scala - there was much going on in the Scala world in the recent years, in which Java is still lagging behind (in fact, I was able to convince one of my colleagues at work to give Scala a try after he saw the introduction to the Rx framework in this book).The book starts by presenting the basics of JVM threading and memory model, which serves as the basic . Although this is more low-level than the rest of the concurrency frameworks in the book, the book does a good job arguing why you need to understand basic JVM concurrency, and when to use threads, locks and monitors. Chapter 3 shows the classic concurrency abstractions, such as concurrent data structures, atomics, and thread pools, and explains lock-free programming. Chapter 4 is where the fun begins - it explains the futures and promises concurrency package, shows how to use it for asynchronous programming, how to functionally compose asynchronous computations, how to write new future combinators using promises, shows how to do proper cancellation and blocking in futures, and explains the Scala Async framework. Chapter 5 introduces parallel collections, shows how they differ from normal collections, discusses operations that can be parallelized, shows how to implement custom parallel operations, and how to evaluate performance in your programs. Chapter 6 introduces Rx, asynchronous programming framework based on first-class event streams, and shows how Rx can be used to build user interfaces and streaming applications. Chapter 7 deals with software transactional memories, discusses how STMs work, shows how to avoid side-effects in transactions, how to execute transactions conditionally, explains how transactional collections work, and, importantly, illustrates how easy it is to create a custom transactional, thread-safe collection. Chapter 8 introduces actor programming using Akka, and covers asynchronous message sends, starting and looking up actors, the basics of actor supervision, as well distributing the application across multiple computers. While Akka is not completely covered in this book, as it is a big topic, this chapter teaches the essentials of Akka, and you will be able to write actor programs after you're done. Chapter 9 shows how to achieve scalability and top performance in concurrent applications, what are the common types of errors in concurrent applications, and how to debug them, and, finally, how to combine different concurrency technologies to build a real-world application - a remote file browser. This is the longest chapter, and arguably, it could have been split into two separate chapters.This is a hands-on book. Every concurrency concept is introduced through a minimal, self-contained example, and you are encouraged to code and try the examples yourself. In almost all places in the book, there is a snippet or a minimal example program that demonstrates or proves the preceding claim. Terms like starvation, deadlock, false sharing and rollbacks are never introduced without the corresponding example program that shows how these effects manifest themselves in practice. These programs are minimal examples, but are realistic and capture the essence of the corresponding real-world programs. I'm sure that, after having written and run the examples, the reader will have no problem recognizing the same effects in practice.Every chapter is concluded with a list of references, and practical program assignments, which test the knowledge from the corresponding chapter, and, in some cases, touch more advanced topics.What I especially liked about this book is that the author shows how different concurrency libraries can be used together. As an occasional by-stander in the Scala world, I've often witnessed propaganda and bias towards specific concurrency technologies. This is not the case only with Scala and its concurrency libraries, but also more broadly, with most programming technologies - proponents of specific programming technologies need to ruthlessly advertise their own frameworks to survive. As a result, they sometimes claim that their technology is the best, applicable to every problem or superior to alternatives. The author dismisses such attitude in two ways. First, he explains the underlying motivations for various concurrency primitives and shows their typical use-cases and usage scenarios. In doing so, he teaches the reader what a specific concurrency construct is most appropriate for. Second, he shows that concurrency primitives coming from different frameworks are not incompatible or mutually exclusive, but that they can and should be used together to tackle a task. For example, futures are ideal for issuing remote procedure calls or asynchronous requests, but parallel collections are more efficient for data-intensive tasks. Actors are great for distributed applications, but software transactional memory composes complex state and allows concurrent access to data. Still, the future can start a data-parallel computation or a transaction, and an Rx stream can send messages to an actor - these primitives support each other.What I'd wish to see more of are advanced concurrency concepts - how does one write his own concurrent data structure, or implement more advanced applications. The book touches performance engineering and achieving best program speeds, and, having read about it, I'd love to learn more. Perhaps a follow-up book about more advanced concurrent programming will address this. Still, this is overall a great book, and will teach you how to think about concurrent programming. I recommend it as an introductory book on concurrent programming, and modern concurrency paradigms.
Amazon Verified review Amazon
Manohar Jonnalagedda Apr 05, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This book if a great resource for learning concurrent programming in Scala. Actually, it is great for learning concurrent programming in general!The book starts out with elementary concurrency building blocks. Each subsequent chapters builds on the blocks seen before, to introduce higher level abstractions, which make it easier to write more complex concurrent programs. At the same time, you won't be lost if you are only interested in later chapters: every chapter gives you sufficient context to understand it in isolation.I love that there are exercises that come with every chapter. They are by no means easy, but very fun and engaging. Many of them are not just programming tasks, but require you to sit down with pen and paper and think for a while. As a result the book satisfies two types of audiences: - The seasoned Scala developer who needs to refer to a resource every once in a while - A newbie who wants to learn about concurrent programming in general, and who is interested in building practical solutions with this knowledge. I definitely fall in this category of people, and am now completely hooked.All in all, this book strikes a pedagogical balance between being a text book and a reference book. Studying it cover to cover (and trying to solve some of the exercises) will give you great insights about concurrent programming.The only issue I have is with the quality (or lack thereof) of the illustrations/pictures. They have a poor scan look, they could definitely be much improved. Also, I wonder if there is going to be some sort of answer key, at least for a selected subset of the exercises.Get your copy now!
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela