csc 536 lecture 2. outline concurrency on the jvm (and between jvms) working problem java...
TRANSCRIPT
![Page 1: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/1.jpg)
CSC 536 Lecture 2
![Page 2: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/2.jpg)
Outline
Concurrency on the JVM (and between JVMs)Working problemJava concurrency tools (review)Solution using traditional Java concurrency toolsSolution using Akka concurrency toolsOverview of Akka
![Page 3: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/3.jpg)
Compute the total size of all regular files stored,directly or indirectly, in a directory
> java Sequential C:\Windows
Total size: 34405975972
Time taken: 47.777222426
Working problem
Users
docsetc
elliesammy
foo.txt bar.txt
xyz.txt
abc.txt
![Page 4: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/4.jpg)
A recursive solution
Basis step: if input is a regular file, return its size
Recursive step: if input is a directory, call function recursively on every item in the directory, add up the returned values and return the sum
(Depth-First Traversal)
Sequential.java
![Page 5: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/5.jpg)
Threads
Should be using threads to traverse filesystem in parallel
A thread is a “lightweight process”A thread really lives inside a process
A thread has its own:program counterstackregister set
A thread shares with other threads in the processcodeglobal variables
![Page 6: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/6.jpg)
Interface Runnable
Must be implemented by any class that will be executed by a thread
Implement method run() with code the thread will run
Anonymous class example:
new Runnable() {
public void run() { // code to be run by thread }
}
![Page 7: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/7.jpg)
Class Thread
Encapsulates a thread of execution in a program To execute a thread:
An instance of a Runnable class is passed as an argument when creating the threadThe thread is started with method start()
Example:
Runnable r = new Runnable() {
public void run() { // code executed by thread }};
new Thread(r).start();
![Page 8: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/8.jpg)
Class Thread
Encapsulates a thread of execution in a program To execute a thread:
An instance of a Runnable class is passed as an argument when creating the threadThe thread is started with method start()
Example:
Runnable r = new Runnable() {
public void run() { // code executed by thread }};
new Thread(r).start();
Issue with threads: synchronizing access to shared data
![Page 9: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/9.jpg)
Producer-Consumer example
SetupA shared memory bufferProducer puts objects into the bufferConsumer reads objects from the buffer
ProducerConsumerTest.java, UnsyncBuffer.java
![Page 10: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/10.jpg)
Producer-Consumer example
SetupA shared memory bufferProducer puts objects into the bufferConsumer reads objects from the buffer
ProducerConsumerTest.java, UnsyncBuffer.java
Problem:producer can over-produce, consumer can over-consume (example of race condition)Need to synchronize (coordinate) the processes
![Page 11: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/11.jpg)
Synchronization
Mechanisms that ensure that concurrent threads/processes do not render shared data inconsistent
Three most widely used synchronization mechanisms in centralized systems are
SemaphoresLocksMonitors
![Page 12: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/12.jpg)
Monitors
Monitor = Set of operations + set of variables + lockSet of variables is the monitor’s stateVariables can be accessed only by the monitor’s operationsAt most one thread can be active within the monitor at a timeTo execute a monitor’s operation, thread A must obtain the monitor’s lockIf thread B holds the monitor’s lock, thread A must wait on the monitor’s queue (wait)Once thread A is done with the monitor’s lock, it must release it so that other threads can obtain it (notify)
![Page 13: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/13.jpg)
Synchronization in Java
Each Java class becomes a monitor when at least one of its methods uses the synchronized modifier
The synchronized modifier is used to write code blocks and methods that require a thread to obtain a lockSynchronization is always done with respect to an object
ProducerConsumerTest.java, SyncBuffer.java
![Page 14: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/14.jpg)
Java Memory model (before Java 5)
Before Java 5: ill defineda thread not seeing values written by other threads a thread observing impossible behaviors by other threads
Java 5 and laterMonitor lock rule: a release of a lock happens before the subsequent acquire of the same lock Volatile variable rule: a write of a volatile variable happens before every subsequent read of the same volatile variable
![Page 15: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/15.jpg)
Disadvantages of synchronization
Disadvantages:Synchronization is error-prone Synchronization blocks threads and takes timeImproper synchronization results in deadlocksCreating a thread is not a low-overhead operationToo many threads slow down the system
![Page 16: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/16.jpg)
Disadvantages of synchronization
Disadvantages:Synchronization is error-prone Synchronization blocks threads and takes timeImproper synchronization results in deadlocksCreating a thread is not a low-overhead operationToo many threads slow down the system
![Page 17: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/17.jpg)
Thread pooling
Thread pooling is a solution to the thread creation and management problem
The main idea is to create a bunch of threads in advance and have them wait for something to doThe same thread can be recycled for different operations
Thread pool components:A blocking queueA pool of threads
![Page 18: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/18.jpg)
Blocking queue
Queue is a sequence of objects
Two basic operations: enqueuedequeue
Blocking Queue:A dequeue thread must block if the queue is emptyAn enqueue thread must add an object to the queue and notify blocked threads
Blocking queue must be thread safe
![Page 19: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/19.jpg)
Blocking Queue dequeue
To dequeue an object from the queue:Wait until the lock on the queue is obtainedIf the queue is empty, release lock and sleepIf the queue is not empty, pop the first element and return it
To enqueue an object to the queue:Wait until the lock on the queue is obtainedPop the first element and return itNotify any sleeping thread
BlockingQueue.java
![Page 20: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/20.jpg)
Thread Pool = threads + tasks
Thread pool = group of threads + queue of Runnable tasks
Thread pool starts by creating the group of threadsEach thread loops indefinitelyIn every iteration, each thread attempts to dequeue a task from the task queueIf the task queue is empty, block on the queueIf a task is dequeued, run the task
Thread pool method execute(task)simply adds the task to the task queue
ThreadPool.java, ThreadPoolTest.java
![Page 21: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/21.jpg)
Java thread pool API
Interface ExecutorService defines objects that run Runnable tasks
Using method execute()
Class Executors defines factory methods for obtaining a thread pool (i.e. an ExecutorService object)
newFixedThreadPool(n) creates a pool of n threads
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(new Runnable() {
public void run() { // task code });
![Page 22: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/22.jpg)
Compute the total size of all regular files stored,directly or indirectly, in a directory
Back to working problem
Users
docsetc
elliesammy
foo.txt bar.txt
xyz.txt
abc.txt
![Page 23: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/23.jpg)
Modern Java Concurrent solution
Use Runnable objectsCreate Runnable object for every (sub)directory
Use thread poolKeeps the number of threads manageableKeep overhead of thread creation lowReuse threads
Avoid sharing stateVariable totalSize onlyAccess must be synchronized
Concurrent1.java Does not work
![Page 24: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/24.jpg)
AtomicLong
Accumulator variable totalSize is incremented by all threads
Must insure that the incrementing operation (the critical section) is not interrupted by a context switch
Solution 1: Use a Java lock to synchronize access to the critical section
Solution 2: Use class AtomicLongmethod addAndGet() executes as a single atomic instruction
![Page 25: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/25.jpg)
Concurrent1 problem
The main thread must wait until all (sub)directories have been processed
No way to know when that happens
Need to:1. keep track of pending tasks, i.e. (directory processing) task
creation and termination 2. Block the main thread until the number of pending tasks is 0
![Page 26: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/26.jpg)
Modern Java Concurrent solution
Use Runnable objectsCreate Runnable object for every (sub)directory
Use thread poolKeeps the number of threads manageableKeep overhead of thread creation lowReuse threads
Avoid sharing stateVariable totalSize onlyAccess must be synchronized
Require synchronization variablesTo terminate the application Concurrent2.java
![Page 27: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/27.jpg)
CountDownLatch
Synchronization tool that allows one or more threads to wait until a set of operations being performed in other threads completes.
initialized with a given countmethod await() blocks until count reaches 0method countdown() decrements count by 1
After count reaches 0, any subsequent invocations of await return immediately.
A CountDownLatch initialized with a count of 1 serves as a simple on/off gate: all threads invoking await wait at the gate until it is opened by a thread invoking countDown().
![Page 28: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/28.jpg)
An Akka/Scala concurrent solution
Use Akka ActorsTask of processing a directory is given to a worker actor by a master actorWorker actor processes directory
computes the total size of all the regular files and sends it to mastersends to master the (path)name of every sub-directory
Master actorInitiates the processsends tasks to worker actorscollects the total sizekeeps track of pending tasks
ConcurrentAkka.java
![Page 29: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/29.jpg)
Akka
Actor-based concurrency frameworkProvides solutions for non-blocking concurrencyWritten in Scala, but also has Java API Each actor has a state that is invisible to other actorsEach actor has a message queue Actors receive and handle messages
sequentially, therefore no synchronization issues
Actors should rarely blockActors are lightweight and asynchronous
650 bytescan have millions of actors running on a few threads on a single machine
![Page 30: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/30.jpg)
Why use Scala and Akka in DSII?
Distributed computingActors do not share state and interact through messagesActor locations (local vs remote) are transparentAkka developed for distributed applications from ground up
TransactionsScala includes an implementation of Software Transactional Memory
Fault toleranceImplements “let-it-crash” semanticsUses supervisor hierarchies that self-heal
Reliable communicationAkka includes an implementation of reactive streams
![Page 31: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/31.jpg)
Actors
StateSupposed to be invisible to other actors
BehaviorThe actions to be taken in reaction to a message
MailboxActors process messages from mailbox sequentially
ChildrenActors can create other actorsA hierarchy of actors
Supervisor strategyAn actor is supervised by its parent
![Page 32: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/32.jpg)
Actors
class First extends Actor {
def receive = {
case "hello" => println("Hello world!")
case msg: String => println("Got " + msg + " from " + sender)
case _ => println("Unknown message")
}
}
object Server extends App {
val system = ActorSystem("FirstExample")
val first = system.actorOf(Props[First], name = "first")
println("The path associated with first is " + first.path)
first ! "hello"
first ! "Goodbye"
first ! 4
}First.scala
![Page 33: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/33.jpg)
Using sbt
Simple Build Tool (http://www.scala-sbt.org/)Easy to set up
Sample build.sbt configuration file
lazy val root = (project in file(".")).
settings (
name := "First Example",
version := "1.0",
scalaVersion := "2.11.6",
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/",
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.3.9"
)
![Page 34: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/34.jpg)
Abstract Class Actor
Extend Actor class and implement method receive
Method receive should have case statements thatdefine the messages the actor handlesimplement the logic of how messages are handleduse Scala pattern matching
class First extends Actor { def receive = { case "hello" => println("Hello world!") case msg: String => println("Got " + msg) case _ => println("Unknown message") }}
![Page 35: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/35.jpg)
Class ActorSystem
Actors form hierarchies, i.e. a system
Class ActorSystem encapsulates a hierarchy of actors
Class ActorSystem provides methods forcreating actorslooking up actors.
At least the first actor in the system is created using it
![Page 36: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/36.jpg)
Class ActorContext
Class ActorContext also provides methods forcreating actorslooking up actors.
Each actor has its own instance of ActorContext that allows it to create (child) actors and lookup references to actors
![Page 37: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/37.jpg)
Obtaining actor references
Creating actorsActorSystem.actorOf()
ActorContext.actorOf()
Both methods return ActorRef reference to new actor
Looking up existing actor by concrete pathActorSystem.actorSelection()
ActorContext.actorSelection()
Both methods return ActorSelection reference to new actor
ActorRef or ActorSelection references can be used to send a message to the actor
![Page 38: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/38.jpg)
Class ActorRef
Immutable and serializable handle to an actoractor could be in the same ActorSystem, a different one, or even another, remote JVMobtained from ActorSystem (or indirectly from ActorContext)
ActorRefs can be shared among actors by message passingyou can serialize it, send it over the wire and use it on a remote host and it will still be representing the same Actor on the original node, across the network.In fact, every message carries the ActorRef of the sender
Message passing conversely is their only purpose
![Page 39: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/39.jpg)
Actor System
![Page 40: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/40.jpg)
Class Props
Props is an Actor configuration objectrecipe for creating an actor including associated deployment info
Used when creating new actors through ActorSystem.actorOfActorContext.actorOf
![Page 41: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/41.jpg)
Sending messages
Messages are sent to an Actor through one ofmethod tell or simply !
means “fire-and-forget”, e.g. send a message asynchronously and return immediately.
method ask or simply ? sends a message asynchronously and returns a Future representing a possible reply
Message ordering is guaranteed on a per-sender basis
Tell is the preferred way of sending messages.No blocking waiting for a messageBest concurrency and scalability characteristics
![Page 42: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/42.jpg)
Message ordering
For a given pair of actors, messages sent from the first to the second will be received in the order they were sent
Causality between messages is not guaranteed!Actor A sends message M1 to actor CActor A then sends message M2 to actor BActor B forwards message M2 to actor CActor C may receive M1 and M2 in any order
Also, message delivery is “at-most-once delivery” i.e. no guaranteed delivery
![Page 43: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/43.jpg)
Message ordering
Akka also guarantees
The actor send ruleThe send of the message to an actor happens before the receive of that message by the same actor.
The actor subsequent processing ruleprocessing of one message happens before processing of the next message by the same actor.
Both rules only apply for the same actor instance and are not valid if different actors are used
![Page 44: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/44.jpg)
Messages and immutability
Messages can be any kind of object but have to be immutable.
Scala can’t enforce immutability (yet) so this has to be by convention.Primitives like String, Int, Boolean are always immutable.Apart from these the recommended approach is to use Scala case classes which are immutable (if you don’t explicitly expose the state) and work great with pattern matching at the receiver sideOther good messages types are scala.Tuple2, scala.List, scala.Map which are all immutable and great for pattern matching
![Page 45: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/45.jpg)
Actor API
Scala trait (think partially implemented Java Interface) that defines one abstract method: receive()
Offers useful references:self: reference to the ActorRef of actorsender: reference to sender Actor of the last received message
typically used for replying to messages
context: reference to ActorContext of actor that includes references to
factory methods to create child actors (actorOf)system that the actor belongs toparent supervisorsupervised children
![Page 46: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/46.jpg)
Ping Pong examples
Second.scala
Third.scala
![Page 47: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/47.jpg)
Scala pattern matching
Scala has a built-in general pattern matching mechanismIt allows to match on any sort of data with a first-match policy
object MatchTest1 extends App {
def matchTest(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
case _ => "many"
}
println(matchTest(3))
println(matchTest(2))
println(matchTest(1))
}
![Page 48: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/48.jpg)
Scala pattern matching
Scala has a built-in general pattern matching mechanismIt allows to match on any sort of data with a first-match policy
object MatchTest2 extends App {
def matchTest(x: Any): Any = x match {
case 1 => "one"
case "two" => 2
case y: Int => "scala.Int: " + y
}
println(matchTest(1))
println(matchTest("two"))
println(matchTest(3))
println(matchTest("four"))
}
![Page 49: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/49.jpg)
Scala case classes
Case classes are regular classes with special conveniencesautomatically have factory methods with the name of the class all constructor parameters become immutable public fields of the classhave natural implementations of toString, hashode, and equals
are serializable by defaultprovide a decomposition mechanism via pattern matching
case class Start(secondPath : String)
case object PING
case object PONG
![Page 50: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/50.jpg)
Scala pattern matching
Scala has a built-in general pattern matching mechanismIt allows to match on any sort of data with a first-match policy
case class Start(secondPath : String)
case object PING
case object PONG
object MatchTest3 extends App {
def matchTest(x: Any): Any = x match {
case Start(secondPath) => "got " + secondPath
case PING => "got ping"
case PONG => "got pong"
}
println(matchTest(Start("path")))
println(matchTest(PING))
}
![Page 51: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/51.jpg)
Scala pattern matching
Scala has a built-in general pattern matching mechanismIt allows to match on any sort of data with a first-match policy
object MatchTest4 extends App {
def length [X] (xs:List[X]): Int = xs match {
case Nil => 0
case y :: ys => 1 + length(ys)
}
println(length(List()))
println(length(List(1,2)))
println(length(List("one", "two", "three")))
}
![Page 52: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/52.jpg)
Scala pattern matchingsealed trait Opcase object OpAdd extends Opcase object OpSub extends Opcase object OpMul extends Opcase object OpDiv extends Op
sealed trait Exp case class ExpNum (n:Double) extends Expcase class ExpOp (e1:Exp, op:Op, e2:Exp) extends Exp
object MatchTest5 extends App { def evaluate (e:Exp) : Double = e match { case ExpNum (v) => v case ExpOp (e1, op, e2) => val n1:Double = evaluate (e1) val n2:Double = evaluate (e2) op match { case OpAdd => n1 + n2 case OpSub => n1 - n2 case OpMul => n1 * n2 case OpDiv => n1 / n2 } }}
![Page 53: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/53.jpg)
Defining Akka message classes
Use Scala case classes
case class Start(secondPath : String)
case object PING
case object PONG
class PingPong extends Actor {
def receive = {
case PING => ...
case PONG => ...
case Start(secondPath) => ...
}
}
![Page 54: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/54.jpg)
An Akka/Scala concurrent solution,in more detail
Use Akka ActorsTask of processing a directory is given to a worker actor by a master actorWorker actor processes directory
computes the total size of all the regular files and sends it to mastersends to master the (path)name of every sub-directory
Master actorInitiates the processsends tasks to worker actorscollects the total sizekeeps track of pending tasks
ConcurrentAkka.scala
![Page 55: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/55.jpg)
class RoundRobinPool
Creating a new worker actor for every task (processing a directory) is not efficient.
tasks are very small so Actor creation overhead is relatively large
Instead, create a pool of worker actors (routees) managed by a router actor of type RoundRobinPool
the router is the parent of the routeesa message (task) sent by some actor A to the router is forwarded to a routee chosen in a round-robin fashion The routee sees actor A as the sender of the message
context.actorOf(RoundRobinPool(50).props(Props[FileProcessor]), name = "workerRouter")
![Page 56: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/56.jpg)
Remote Actors
Distributed by defaultActor interactions are asynchronous messagesLocal actor interactions are optimization of general case (remote actors)
![Page 57: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/57.jpg)
Remoting configuration (server)Add dependency to build.sbtlibraryDependencies += "com.typesafe.akka" %% "akka-remote" % "2.3.9"
Add to application.confserver {
include "common"
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
remote {
netty.tcp {
hostname = "127.0.0.1"
port = 2552
}
}
}
}
![Page 58: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/58.jpg)
Remoting Configuration
application.conf configuration:
Change provider from akka.actor.LocalActorRefProvider to akka.remote.RemoteActorRefProvider
Transport mode: specifies transport protocol
Host name
Port number - the port the actor system should listen on, set to 0 to have it chosen automatically (e.g., for clients)
![Page 59: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/59.jpg)
Remoting configuration (client)Add dependency to build.sbtlibraryDependencies += "com.typesafe.akka" %% "akka-remote" % "2.3.9"
Add to application.confremotelookup {
include "common"
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
remote {
netty.tcp {
hostname = "127.0.0.1"
port = 0
}
}
}
}
![Page 60: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/60.jpg)
Client-side code
To obtain the handle to a remote actor:ActorSystem method actorSelection() takes the URL of a remote actor and returns an ActorSelection to it
val joe = system.actorSelection("akka.tcp://[email protected]:2552/user/joe”)
You can now send messages to the remote actor as usual
To acquire an ActorRef for an ActorSelectionyou need to send a message to the selectionthe actor should replyuse the reference of the reply from the actor
![Page 61: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/61.jpg)
Remoting example
server.scala + application.conf
client.scala + application.conf
Project remote
![Page 62: CSC 536 Lecture 2. Outline Concurrency on the JVM (and between JVMs) Working problem Java concurrency tools (review) Solution using traditional Java concurrency](https://reader030.vdocuments.net/reader030/viewer/2022032708/56649e875503460f94b8a464/html5/thumbnails/62.jpg)
Remoting example
server.scala + application.conf
client.scala + application.conf
Project remote2