![Page 1: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/1.jpg)
Concurrency
Unleash your processor(s)Václav Pech
![Page 2: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/2.jpg)
The evil accumulator
int sum=0;for(int i : collection) sum += i;
![Page 3: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/3.jpg)
We’re quad core already
Beware: More cores to come shortly!
![Page 4: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/4.jpg)
Stone age of parallel SW
Dead-locks Live-locks Race conditions Starvation
Shared Mutable State
![Page 5: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/5.jpg)
Lock and synchronize
Multithreaded programs today work mostly by accident!
![Page 6: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/6.jpg)
Making code transactional
@Transactionalpublic void findAllFoosAround() { //tx agnostic code here}
withTransaction { //tx agnostic code here}
![Page 7: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/7.jpg)
Map/Reduce
Fork/Join
Actors
STM
Dataflow
Agent
Can we do better?
![Page 8: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/8.jpg)
Collections (GPars)
images.eachParallel {it.process()}
documents.sumParallel()
candidates.maxParallel {it.salary}.marry()
![Page 9: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/9.jpg)
Parallel Arrays (jsr-166y)
ParallelArray namesOfWomen = people.withFilter(aWoman).withMapping(retrieveName).all();
Ops.Predicate aWoman = new Ops.Predicate() { public boolean op(Person friend) {return !friend.isMale();}};
Ops.Op retrieveName = new Ops.Op() { public Object op(Person friend) {return friend.getName();}};
![Page 10: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/10.jpg)
Fork/Join
Solve hierarchical problems
Divide and conquer Merge sort, Quick sort Tree traversal File scan / search …
[a, b, c, d, e, f, g, h]
[a, b, c, d] [e, f, g, h]
[a, b] [c, d] [e, f] [g, h]
![Page 11: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/11.jpg)
Fork/Join (GPars)
protected void computeTask() { long count = 0; file.eachFile { if (it.isDirectory()) { println "Forking a thread for $it" forkOffChild(new FileCounter(it)) } else { count++ } } return count + childrenResults.sum() }
Waits for children without blocking the thread!
![Page 12: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/12.jpg)
Asynchronous invocation
Future f = threadPool.submit(calculation);…System.out.println(“Result: “ + f.get());
main calculation
get()
![Page 13: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/13.jpg)
Dataflow Concurrency
No race-conditions No live-locks Deterministic deadlocks
Completely deterministic programs
BEAUTIFUL code (Jonas Bonér)
![Page 14: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/14.jpg)
Dataflow Variables / Promisesmain task2 task3
x
yz
task1
![Page 15: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/15.jpg)
DataFlows (GPars)
def df = new DataFlows()
task { df.z = df.x + df.y }task { df.x = 10 }task { df.y = 5 }
assert 15 == df.z
![Page 16: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/16.jpg)
Promises (Clojure)
(def x (promise)) (def y (…))(def z (…))
(future (deliver z (+ @x @y)))(future (deliver x 10))(future (deliver y 5))
(println @z)
![Page 17: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/17.jpg)
Dataflow Operators (GPars)
operator(inputs: [stocksStream], outputs: [pricedStocks]) {stock -> def price = getClosing(stock, 2008) bindOutput(0, [stock: stock, price: price]) }
*
+<>
![Page 18: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/18.jpg)
Actors
Isolated Communicating
Immutable messages Active
Pooled shared threads Activities
Create a new actorSend a messageReceive a message
ActorActorActorActorActorActorActor
TTTThread pool
![Page 19: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/19.jpg)
Actors use
GateKeeper
Form
HTTP
FingerPrints
AddressCheck
EmailCheckProcess
FraudDetect
Response
SOAP
SMTP
![Page 20: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/20.jpg)
Actors patternsEnricher
Router
Translator
Endpoint
Splitter
Agregator
Filter
Resequencer
Checker
![Page 21: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/21.jpg)
Creating Actors (GPars)
class MyActor extends AbstractPooledActor { void act() { def buddy = new YourActor() buddy << ‘Hi man, how\’re things?’ def response = receive() }}
![Page 22: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/22.jpg)
Creating Actors (Scala)
val myActor = actor { loop { react { case x:Int=>reply 2*x case s:String=>reply s.toUpperCase() } }}myActor ! 10
![Page 23: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/23.jpg)
Creating Actors (Akka - Scala)
class MyActor extends Actor { def receive = { case "Hello" => reply("World") case Register(user, sender) => val registrationCode = register(user) sender ! SuccessfulRegistration(registrationCode) case _ => throw new RuntimeException("unknown
message")} }
Example form http://doc.akkasource.org/actors
![Page 24: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/24.jpg)
Continuation Style
loop { … react { … react {/*schedule the block; throw CONTINUE*/ … } //Never reached } //Never reached}//Never reached
![Page 25: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/25.jpg)
Creating Actors (Jetlang)
Fiber fiber = new ThreadFiber();fiber.start();Channel<String> channel = new MemoryChannel<String>();
Callback<String> runnable = new Callback<String>() { public void onMessage(String msg) { log(msg.toUpperCase()); }};channel.subscribe(fiber, runnable);channel.publish("hello");
Based on sample code from http://code.google.com/p/jetlang/
![Page 26: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/26.jpg)
Java actor frameworks
JetlangKilimActorFoundryActoromAkka…
![Page 27: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/27.jpg)
Agent
Lock Shared Mutable State in a Safe
Alterthe
State
Alterthe
State
![Page 28: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/28.jpg)
Agent inside
Double IncrementAdd 25
Message Queue
36 thread
![Page 29: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/29.jpg)
Agent (Clojure)
(defn increment [c] (+ c 1))(defn decrement [c] (- c 1))(defn add [c delta] (+ c delta))
(def a (agent 0))
(send a increment) | (send a decrement) | (send a add 25) | …
(await a) (println @a)
![Page 30: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/30.jpg)
Agent (ScalaAgent)
def increment(x: Long) = x + 1def decrement(delta : Long)(x: Long) = x - delta val agent = Agent(0L)
agent(increment _) agent(decrement(3) _) agent{_ + 100} println(agent get)
![Page 31: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/31.jpg)
STM (Clojure)
(defstruct person :name :gender :age)(def people (ref #{}))
(dosync (alter people conj (struct person "Joe" "male" 39)) (alter people conj (struct person "Alice" "female" 27)) (alter people conj (struct person "Dave" "male" 41)))
![Page 32: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/32.jpg)
STM (Akka - Scala)
atomic { .. // do something within a transaction }
atomic(maxNrOfRetries) { .. }atomicReadOnly { .. }
atomically { .. // try to do something } orElse { .. // if tx clash; try do do something else }
Sample taken from Akka documentation - http://doc.akkasource.org/stm
![Page 33: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/33.jpg)
Persistent Data Structures
Illustration taken from Rich Hickey's presentation. Copyright Rich Hickey 2009
![Page 34: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/34.jpg)
Our original intention
@Transactionalpublic void findAllFoosAround() { //tx agnostic code here}
withTransaction { //tx agnostic code here}
![Page 35: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/35.jpg)
The reality
images.eachParallel { //concurrency agnostic code here}
def myActor = actor { //concurrency agnostic code here}
(dosync /*concurrency agnostic code here*/)…
![Page 36: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/36.jpg)
Summary
Parallelism is not hard, multi-threading is
Systems that interface to the real world are easier to design in parallel
Jon Kerridge, Napier University
![Page 37: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/37.jpg)
Tips
Java JSR-166y - Fork/Join, Parallel Arrays, Multiverse
Clojure STM, Atoms, Agents, Promises
Scala Actors, Akka, ScalaAgent
Groovy GPars – actors, agent, dataflow, fork/join, map/reduce
![Page 38: Concurrency · Making code transactional @Transactional public void findAllFoosAround() {//tx agnostic code here} withTransaction {//tx agnostic code here}](https://reader034.vdocuments.us/reader034/viewer/2022042414/5f2e0d213cce5d7302149a22/html5/thumbnails/38.jpg)
Questions?