10. State of the Practice
public class Counter {
private int count = 0;
public int increment() {
synchronized(this) {
return ++count;
}
}
}
11.
12. JCIP says:
• It’s the mutable state, stupid.
• Make fields final unless they need to be mutable.
• Immutable objects are automatically thread-safe.
• Encapsulation makes it practical to manage the complexity.
• Guard each mutable variable with a lock.
• Guard all variables in an invariant with the same lock.
• Hold locks for the duration of compound actions.
• A program that accesses a mutable variable from multiple threads
without synchronization is a broken program.
• Don’t rely on clever reasoning about why you don’t need to
synchronize.
• Include thread safety in the design process - or explicitly document
that your class is not thread-safe.
• Document your synchronization policy.
13. JCIP says:
• It’s the mutable state, stupid.
• Make fields final unless they need to be mutable.
• Immutable objects are automatically thread-safe.
• Encapsulation makes it practical to manage the complexity.
• Guard each mutable variable with a lock.
• Guard all variables in an invariant with the same lock.
• Hold locks for the duration of compound actions.
• A program that accesses a mutable variable from multiple threads
without synchronization is a broken program.
• Don’t rely on clever reasoning about why you don’t need to
synchronize.
• Include thread safety in the design process - or explicitly document
that your class is not thread-safe.
• Document your synchronization policy.
15. The problem with shared state concurrency
...is the shared state.
16. Actors
• No shared state
• Lightweight processes
• Asynchronous message-passing
• Buffer messages in a mailbox
• Receive messages with pattern matching
21. Erlang
• Invented at Ericsson
• Functional language
• Dynamic typing
• Designed for concurrency, fault-tolerance
22. Single assignment
Eshell V5.6.3 (abort with ^G)
1> A = 4.
4
2> A.
4
3> A = 6.
** exception error: no match of right hand
side value 6
4> A = 2*2.
4
39. Running Rings
1> c(ring).
2> T=ring:startTimer().
3> R=ring:startRing(100,T).
spawned 100 in 241 microseconds
4> R ! start.
{1230,863064,116530} Starting message
{1230,863064,879862} Around ring 10000 times
{1230,863065,642097} Around ring 20000 times
...etc
{1230,863140,707023} Around ring 990000 times
{1230,863141,471193} Around ring 1000000 times
Start={1230,863064,116875}
Stop={1230,863141,471380} Elapsed=77354505
5> R20k = ring:startRing(20000,T).
spawned: 20000 in 118580 microseconds
40. Processes and
Messages
• Processes cheap to create (10ks < second)
• Create many processes (10ks to 100ks)
• Messages very fast to send (1M / second)
51. Facebook Chat
“For Facebook Chat, we rolled our own subsystem
for logging chat messages (in C++) as well as an epoll-
driven web server (in Erlang) that holds online users'
conversations in-memory and serves the long-polled
HTTP requests. Both subsystems are clustered and
partitioned for reliability and efficient failover. ”
Reference: http://www.facebook.com/note.php?note_id=14218138919
55. Scala Rings
case TokenMessage(id,value) if id == nodeId => {
val nextValue = value+1
if(nextValue % 10000 == 0)
log(quot;Around ring quot; + nextValue + quot; timesquot;)
if(nextValue == 1000000) {
timer ! StopMessage
timer ! CancelMessage
nextNode ! StopMessage
exit
} else {
nextNode ! TokenMessage(id, nextValue)
}
}
case TokenMessage(id,value) => {
nextNode ! TokenMessage(id,value)
}
}
56. Comparison to Erlang
• receive-based actors cheap to create
(Erlang about 3x faster)
• Can also create many processes
• Messages also fast to send (Erlang about 2x
faster)
57. • Java-based framework with compile-time weaving
• Tasks - lightweight threads/processes/etc
• @pausable - let task be paused during execution
• sleep / yield
• Mailbox (typed via generics) - single consumer
• Messaging - mutable (in limited ways)
58. Kilim Ring
import kilim.Mailbox;
import kilim.Task;
import kilim.pausable;
public class NodeActor extends Task {
private final int nodeId;
private final Mailbox<Message> inbox;
private final Mailbox<Message> timerInbox;
private Mailbox<Message> nextInbox;
public NodeActor(int nodeId,
Mailbox<Message> inbox,
Mailbox<Message> timerInbox) {
this.nodeId = nodeId;
this.inbox = inbox;
this.timerInbox = timerInbox;
}