Concurrency 1 Bloch
Concurrency 1 Bloch
Part 3: Concurrency
Introduction to concurrency
17-214 1
Administrivia
17-214 2
Today’s lecture: concurrency motivation and primitives
• Why concurrency?
– Motivation, goals, problems, …
• Concurrency primitives in Java
• Coming soon (not today):
– Higher-level abstractions for concurrency
– Program structure for concurrency
– Frameworks for concurrent computation
17-214 6
Moore’s Law (1965) – number of transistors on a chip
doubles every two years
17-214 7
CPU Performance and Power Consumption
17-214 8
One option: fix the symptom
17-214 9
One option: fix the symptom
17-214 10
17-214 11
Concurrency then and now
17-214 12
We are all concurrent programmers
17-214 13
Aside: Concurrency vs. parallelism, visualized
Thread1
Thread2
Thread3
17-214 14
Basic concurrency in Java
Review
17-214 15
Example: Money-grab (1/2)
17-214 16
Example: Money-grab (2/2)
What would you expect this program to print?
bugsThread.start(); daffyThread.start();
bugsThread.join(); daffyThread.join();
System.out.println(bugs.balance() + daffy.balance());
}
17-214 17
What went wrong?
• Daffy & Bugs threads had a race condition for shared data
– Transfers did not happen in sequence
• Reads and writes interleaved randomly
– Random results ensued
17-214 18
The challenge of concurrency control
17-214 19
Shared mutable state requires concurrency control
17-214 20
An easy fix for our BankAccount program:
17-214 21
Concurrency control with Java’s intrinsic locks
with an explicit lock
• synchronized (lock) { … }
– Synchronizes entire block on object lock; cannot forget to unlock
– Intrinsic locks are exclusive: One thread at a time holds the lock
– Intrinsic locks are reentrant: A thread can repeatedly get same lock
Thread1
Thread2
Thread3
17-214 22
Concurrency control with Java’s intrinsic locks
with an implicit lock
• synchronized (lock) { … }
– Synchronizes entire block on object lock; cannot forget to unlock
– Intrinsic locks are exclusive: One thread at a time holds the lock
– Intrinsic locks are reentrant: A thread can repeatedly get same lock
• synchronized on an instance method
– Equivalent to synchronized (this) { … } for entire method
• synchronized on a static method in class Foo
– Equivalent to synchronized (Foo.class) { … } for entire method
17-214 23
Another example: serial number generation
What would you expect this program to print?
17-214 24
What went wrong?
17-214 25
Again, the fix is easy
17-214 26
But you can do better!
java.util.concurrent is your friend
17-214 27
Some actions are atomic
Precondition: Thread A: Thread B:
int i = 7; i = 42; ans = i;
17-214 28
Some actions are atomic
Precondition: Thread A: Thread B:
int i = 7; i = 42; ans = i;
• What are the possible values for ans?
i: 00000…00000111
…
i: 00000…00101010
ans: 00000…00101111
17-214 29
Some actions are atomic
Precondition: Thread A: Thread B:
int i = 7; i = 42; ans = i;
• What are the possible values for ans?
i: 00000…00000111
…
i: 00000…00101010
• In Java:
– Reading an int variable is atomic
– Writing an int variable is atomic
17-214 30
Bad news: some simple actions are not atomic
All are
ans: 00000…00101010 (42) possible!
17-214 31
Yet another example: cooperative thread termination
How long would you expect this program to run?
TimeUnit.SECONDS.sleep(5);
stopRequested = true;
}
}
17-214 32
What went wrong?
17-214 33
Why is synchronization required for communication
among threads?
• Naively: Process
– Thread state shared in memory Thread Thread
Memory
• A (slightly) more accurate view:
– Separate state stored in registers and caches, even if shared
Process
Thread Thread
Cache Cache
Memory
17-214 34
How do you fix it?
TimeUnit.SECONDS.sleep(5);
stopRequested = true;
}
}
17-214 36
Summary
17-214 37