This document provides an overview of concurrency concepts including:
- The speaker discusses some basic JVM knowledge, concurrency concepts, and personal design suggestions.
- Key concurrency topics like reorder, happens-before relationships, volatile fields, and CopyOnWriteArrayList are summarized.
- Common concurrency patterns like producer-consumer, readers-writers, and dining philosophers problems are explained.
- The goal is to make developers aware of concurrency issues and provide resources to study the topic further.
2. Agenda
● Some JVM knowledge
● Some basic concurrency concepts
● Some personal design suggestions
3. Reference
● Some JVM knowledge - Java Concurrency in Practice
● Some basic concurrency concepts - Clean Code
● Some personal design suggestions
4. Won’t be mentioned
● Practices to write concurrency program
● Patterns or anti-patterns in concurrency programming
● java.util.concurrent API example
● More detail in JVM
They are big topics, maybe other Tech Talks.
Or we can discuss with each other for interesting.
5. Target audience
● Java developers who don’t know about concurrency
● Your code will run in multi-threaded environment
6. Goal
● Be aware concurrency issue while programming
● Get some material or direction to study
● Let concurrency become a famous discussion between developers
7. Why Concurrency
● CPU core size maybe 8-24
But there are thousands of threads…
Currency must be a very important topic in development
8. What is Concurrency?
… This[Concurrency] means that even if the concurrent units
of the program, algorithm, or problem are executed
out-of-order or in partial order, the final outcome will
remain the same…
~ WIKI
9. What is “out-of-order”?
In this paradigm [out-of-order-execution], a processor
executes instructions in an order governed by the availability
of input data, rather than by their original order in a
program. In doing so, the processor can avoid being idle
while waiting for the preceding instruction to complete to
retrieve data for the next instruction
~ WIKI
10. Is it related to my java code?
Java code Reordered (Maybe)
public int test() {
int a = 1;
a++;
int b = 2;
b++;
return a+b;
}
public int test() {
int a = 1, b = 2; // load var and data
a++; // read and write
b++; // read and write
return a+b; // result is same after reordered
}
// Should be faster in a smater way…
// Most important is we don’t know the order
11. It seems not my business, should I care?
First of all, the program will be loaded to a CPU core to run.
CPU Core1 CPU Core2
Program in memory
Program Program
12. It seems not my business, should I care?
CPU only care about to run program faster and correct.
CPU don’t care about the status between threads without special command.
What will happen in main thread?
Thread A Thread B
a=1;
x=b;
b=1;
y=a;Main Thread
1. Start thread A
2. Start thread B
3. Get x and y
int x=0,y=0;
int a=0,b=0;
13. It seems not my business, should I care?
We can’t expect the results are always identical…
Thread A
Execution
1. a=1,x=0
2. a=1,x=1
Thread B
Execution
1. b=1,y=0
2. b=1,y=1
int x=0,y=0;
int a=0,b=0;
a=1;
x=b;
b=1;
y=a;Main Thread
1. Start thread A
2. Start thread B
3. Read x and y
Result:
1. x=0,y=1 // B finished
2. x=1,y=0 // A finished
3. x=1,y=1 // Both finished
4. x=0,y=0 // Both not finished
// and reordered
int x=0,y=0;
int a=0,b=0;
14. It seems not my business, should I care?
● Result 1: x=0, y=1
ThreadA ThreadB Main Thread
Code a=1;
x=b;
b=1;
y=a;
Start thread A
Start thread B
Read x and y
Cycle 1 a=1; b=1;
Cycle 2 y=a; Get x=0, y=1
Cycle 3 x=b;
15. It seems not my business, should I care?
● Result 2: x=1, y=0
ThreadA ThreadB Main Thread
Code a=1;
x=b;
b=1;
y=a;
Start thread A
Start thread B
Read x and y
Cycle 1 a=1; b=1;
Cycle 2 x=b; Get x=1, y=0
Cycle 3 y=a;
16. It seems not my business, should I care?
● Result 3: x=1, y=1
ThreadA ThreadB Main Thread
Code a=1;
x=b;
b=1;
y=a;
Start thread A
Start thread B
Read x and y
Cycle 1 a=1; b=1;
Cycle 2 x=b; y=a;
Cycle 3 Get x=1, y=1
17. It seems not my business, should I care?
● Result 4: x=0, y=0
ThreadA ThreadB Main Thread
Code a=1;
x=b;
b=1;
y=a;
Start thread A
Start thread B
Read x and y
Cycle 1 x=b; y=a;
Cycle 2 a=1; b=1;
Cycle 3 Get x=0, y=0
18. Another example more close to our daily work
class APManager {
ArrayList<AP> aps;
// online, offline AP
// register, unregister AP
}
class APStatusListener {
ArrayList<AP> aps; // set from APManager
public void infiniteCheck() {
while (true) {
for (AP ap: aps) {
if (ap.isOnline()) {...}
else {...}
}
}
}
}class AP {
String status; // online, offline
}
What problem in APStatusListener?
19. Another example more close to our daily work
class APManager {
ArrayList<AP> aps;
// online, offline AP
// register, unregister AP
}
class APStatusListener {
ArrayList<AP> aps; // set from APManager
public void infiniteCheck() {
while (true) {
for (AP ap: aps) {
if (ap.isOnline()) {...}
else {...}
}
}
}
}
May be always initial data.
No new AP
No AP will be removed
No status change
class AP {
String status; // online, offline
}
20. How to fix?
class APManager {
final CopyOnWriteArrayList<AP> aps;
// online, offline AP, change AP.status
// register, unregister AP
}
class APStatusListener {
List<AP> aps; // set from APManager
public void infiniteCheck() {
while (true) {
for (AP ap: aps) {
if (ap.isOnline()) {...}
else {...}
}
}
}
}class AP {
volatile String status; // online, offline
}
21. How to fix?
class APManager {
final CopyOnWriteArrayList<AP> aps;
// online, offline AP, change AP.status
// register, unregister AP
}
class APStatusListener {
List<AP> aps; // set from APManager
public void infiniteCheck() {
while (true) {
for (AP ap: aps) {
if (ap.isOnline()) {...}
else {...}
}
}
}
}
class AP {
volatile String status; // online, offline
}
final => APStatusListener will see initialized aps
CopyOnWriteArrayList => APStatusListener see modified element
(Of course you can declare aps with List<AP> and CopyOnWriteArrayList<AP> implementation)
volatile => APStatusListener see AP status change
22. How it works?
After JAVA 5
JVM introduce JSR-133 Java Memory Model
who defined happens-before relationship
and give final field a special meaning to make things happen.
23. What is happens-before relationship?
It’s rules guarantee by JVM, used to define program order.
● Each action in a thread happens before every subsequent action in that thread.
● An unlock on a monitor happens before every subsequent lock on that monitor.
● A write to a volatile field happens before every subsequent read of that volatile.
● A call to start() on a thread happens before any actions in the started thread.
● All actions in a thread happen before any other thread successfully
returns from a join() on that thread.
● If an action a happens before an action b, and b happens before an action c,
then a happens before c.
24. How about final field?
JSR-133 defined that after an object was properly
constructed, a final field assigned in constructor can be
visible by all threads.
25. How about final field in the JVM before Java 5?
The final field in old JVM has no difference between general
field except it need assign value in constructor.
Developer still need to use synchronization to ensure the
variable modification visible in all threads.
26. What is CopyOnWriteArrayList?
It's a thread safe ArrayList implementation in
java.util.concurrent package, introduced from Java 5. It also
leverage Java Memory Model to make sure modifications
visible to other threads.
29. Magic in ReentrantLock
setState write value to volatile state, make sure all lock holder get latest state.
Thus don’t need synchronized tryRelease
30. volatile is not a siliver buttlet
● It can’t perform N++ operation with just N++..
volatile int n = 0; Thread 1 Thread 2
n++; n = 0, n = n+1 n = 0, n = n+1
Get n n = 1; n = 1
31. How to perform N++ atomically?
● syncrhonized (monitor lock)
int n = 0; // don’t need volatile if using synchronized
public synchronized int incremenetAndGet() {
n++;
}
32. How to perform N++ atomically?
● AtomicInteger#incrementAndGet
39. Mutual Execution
Only one thread can access shared data or a shared resource at a time.
Such as Java Synchronization
40. Starvation
One thread or a group of threads is prohibited from proceeding for an excessively
long time or forever.
Ex. Lower priority tasks may encounter Starvation.
(Because always higher priority task)
41. Deadlock
Two or more threads wait for each other to finish. Each thread has a resource that
the other thread requires and neither can finish until gets the other resource.
Thread 1 Thread 2
Lock1
Lock2
acquire acquire
waitwait
Thread1 and Thread2 all need
acquire Lock1 and Lock2
to do something.
But the order is different so
deadlock may happen.
Note: Acquire and release locks in
the same order can prevent
deadlock
42. Livelock
A thread often acts in response to the action of another thread. If the other
thread's action is also a response to the action of another thread, then livelock
may result.
Example:
A boy and girl are dating in a restaurant. They are shy.
They order a cup of drink to share.
They try to take the drink but find another also want to drink so stop back.
And again, and again, and again...until someone stop...or never...
44. Producer-Consumer
● Behavior
a. Producer threads create work in a queue
b. Consumer threads acquire work from queue and complete it
● Challenge
a. Queue is the bound resource
b. Producer need wait for free space in queue
c. Consumer need wait until something in queue
d. Producer may need notify Consumer queue is not empty
e. Consumer may need notify Producer queue is empty
45. Producer-Consumer
● Benefit
a. Observer pattern, used to decouple model or process
b. Easy to tune thread pool
because producer and consumer have different resource occupation style
● Risk
a. Needless decoupling cause duplication and hard to define model responsibility
b. Too many decoupliing cause system too complex and waste resource
● Example
a. Message Queue
b. Thread Pool
46. Readers-Writers
● Behavior
○ A shared resource serves as a source of information for Readers
○ Writers may update the shared resource
● Challenge
○ Throughput issue
■ Writer prevent reader read while updating
■ Reader prevent writer write while reading
○ Stale information problem while reader allowing writer update
47. Readers-Writers
● Risk
○ Try to prevent read stale data
■ System load heavy
■ Useless lock
■ User don’t care
● Example
○ Cassandra
○ ElasticSearch
48. Dining Philosophers
● Behavior
○ Number of philosophers sitting around a circle table
○ Philosophers can’t eat when they are thinking
○ Philosophers need pick up forks on either side of them and eat
○ Philosophers can’t eat unless they hold two forks
● Challenge
○ If the philosopher to his right or left is already using
one of the forks he need, he must wait until that
philosopher finish eating and put forks back down.
○ Deadlock when everyone pick one fork and wait for another finish
○ Livelock when everyone put forks back down
and try again later
49. Dining Philosophers
● Challenge
○ Throughput: A philosopher need to wait other finish, although he is not thinking
● Example
○ Programmatically
■ Need hold 2 or more locks to do something
● How to solve
○ A waiter track every forks status,
philosopher need ask waiter and pick up forks
○ Prioritize forks, philosophers need follow the priority
to pick up/put back forks
○ Philosopher who has no fork get a ticket,
use a ticket to replace 2 forks to eat.
Finished philosopher give forks to who has a ticket.
50. Personal design suggestion
Define the model you are designing is Single-source-of-truth or not.
● Better to use Singleton when it’s Single-source-of-truth.
This model must be thread safe
● Build immutable object if it’s the copy of Single-source-of-truth.
● Be aware the copy of Single-source-of-truth maybe stale
● Single Responsibility Principle is basic
51. Example
Seat it self
(Single-source-of-truth)Seat list 1 Seat list 2
Manager1
Manager2
Employee1
Employee2
We are going to change seats because of re-org.
Managers ask some people for change requirements..
52. Example
Seat it self
(Single-source-of-truth)
Seat list 1 Seat list 2
Manager1
Manager2
Employee1
Employee2
Singleton naturally
Maybe stale.
Need compare and swap
We are going to change seats because of re-org.
Managers ask some people for change requirements..
53. Study Materials
● Java Concurrency in Practice
● Clean Code
● Effective Java
● JSR-133 Java Memory Model
● JSR-133 FAQ
● LLVM Atomics