CPL 2016, week 5 Inter-thread collaboration Oleg Batrashev - - PowerPoint PPT Presentation
CPL 2016, week 5 Inter-thread collaboration Oleg Batrashev - - PowerPoint PPT Presentation
CPL 2016, week 5 Inter-thread collaboration Oleg Batrashev Institute of Computer Science, Tartu, Estonia March 7, 2016 Overview Studied so far: 1. Inter-thread visibility : JMM 2. Inter-thread synchronization : locks and monitors 3. Thread
Overview
Studied so far:
- 1. Inter-thread visibility: JMM
- 2. Inter-thread synchronization: locks and monitors
- 3. Thread management: executors, tasks, cancelation
- 4. Inter-thread communication: confinements, queues, back
pressure Today:
◮ Inter-thread collaboration: actors, inboxes, state diagrams
Next weeks:
◮ Asynchronous execution: callbacks, Pyramid of Doom, Java
8 promises.
◮ Performance considerations: asynchronous IO, Java 8
streams.
Inter-thread collaboration 98/121
- Escaping locking hell
How to solve locking hell?
◮ threads travel through code layers (and back using callbacks) ◮ take locks spontaneously – difficult to reason, deadlock danger
GUI Middle Net layer
◮ using producer/transducer/concumer model is a solution
◮ not exactly what is needed for an application, because ◮ it is lock-step execution – data stream processing, but ◮ we need to manage spontaneous or unexpected events: user
clicks or network failures.
◮ Actor model is the next step.
Inter-thread collaboration 99/121 Actor model -
Outline
Inter-thread collaboration Actor model Message handling
State vs message centric Inboxes
Reasoning with actors Actor frameworks
Inter-thread collaboration 100/121 Actor model -
Passive and active objects
A passive object:
◮ does not have its thread ◮ any thread can enter it ◮ required to synchronized access to its data ◮ 99% of the objects in typical programs
An active object:
◮ has its own thread ◮ does not allow external thread to run its methods ◮ does not need to synchronize access to its data ◮ communicates with external parts through messages ◮ even when used, not recognized as such by programmers
(Swing)
Inter-thread collaboration 101/121 Actor model -
Actor definition
Actor is basicly an active object:
- 1. actor state (data), usually inside an object
- 2. dedicated thread – total single thread confinement
◮ data is accessed only from this thread
- 3. dedicated message queue
◮ the thread reads and processes messages – changes its state ◮ other threads put messages to the queue to communicate with
the actor State
queue send()
process
modify take()
Actor
Inter-thread collaboration 102/121 Actor model -
Simple actor example
- 1. Counter actor holds integer value, start at 0
- 2. Queue may hold messages inc, reset, print:
◮ inc – increase counter by one, reset – set value to zero
public enum MType { INC , RESET , PRINT } private BlockingQueue <MType > queue = new LinkedBlockingQueue < >(); private int value = 0; public Counter () { new Thread(this ). start (); } public void send(MType message) { queue.put(message ); } public void run () { while (true) { // read and process messages MType msg = queue.take (); if (msg == MType.INC) value += 1; else if (msg == MType.RESET) value = 0; else if (msg == MType.PRINT) System.out.println(value ); } } public static void main(String [] args) { Counter cnt = new Counter (); // create the actor cnt.send(MType.INC ); cnt.send(MType.PRINT ); cnt.send(MType.RESET ); cnt.send(MType.PRINT ); }
Inter-thread collaboration 103/121 Actor model -
More than a transducer
Transducer from previous lecture also
- 1. runs in its own thread
- 2. reads messages from a queue
- 3. may have internal state
Actor is the same, but they have different goals
◮ transducer is meant to be more data transforming entity ◮ actor is autonomous communicating entity
◮ e.g., it may tolerate communication problems and failures of
- ther actors in the system
For actor it is natural to have
- 1. communicate with many different actors
- 2. more complex internal state, e.g. including substates
- 3. have sophisticated message filtering and handling
Inter-thread collaboration 104/121 Actor model -
Another actor example
◮ logging of messages (warnings,errors) in application is often
moved to separate thread
◮ it requires writes to disc (or other IO) ◮ it is asynchronous and may be postponed
◮ logging actor
◮ state is ACTIVE and NOTACTIVE ◮ queue may contain LOG, START, and STOP messages ◮ LOG is ignored in NOTACTIVE state, otherwise log is written ◮ START and STOP switch between ACTIVE and NOTACTIVE
◮ any thread may add info with LOG message ◮ messages are put to the queue and written out by the actor
thread (code examples will follow)
Inter-thread collaboration 105/121 Message handling -
Outline
Inter-thread collaboration Actor model Message handling
State vs message centric Inboxes
Reasoning with actors Actor frameworks
Inter-thread collaboration 106/121 Message handling -
State-message matrix
◮ state-message matrix for the logging example
messages/states ACTIVE NOTACTIVE START →ACTIVE LOG(text) print(text) STOP →NOTACTIVE
◮ empty cell is ignoring the message
◮ e.g. when service is not active, then STOP and LOG messages
are ignored
◮ arrows show state transition ◮ could write if(state==..
&& message.type==..) {..} There are two corner cases how to structure your code:
- 1. state-centric – if(state==) is outer condition
- 2. message-centric – if(message.type==) is outer condition
Inter-thread collaboration 107/121 Message handling - State vs message centric
State centric handling
◮ for each state the messages that are handled can be easily
spotted
◮ e.g. ACTIVE state handles LOG and STOP messages
◮ for each message the states where the message is handled
cannot be easily spotted
◮ e.g. START is handled on NOTACTIVE only, but in case of
longer code we have to go through all of it to verify this
if (state == State.NOTACTIVE) { // first check state if (msg.type == MType.START) { state = State.ACTIVE; } } else if (state == State.ACTIVE) { if (msg.type == MType.LOG) { log (( Log)msg ); } else if (msg.type == MType.STOP) { state = State.NOTACTIVE; } }
Inter-thread collaboration 108/121 Message handling - State vs message centric
Message centric handling
◮ opposite to the previous, it is easy to see in which states a
message is handled
◮ e.g. LOG is handled only in ACTIVE state
if (msg.type == MType.START) { if (state == State.NOTACTIVE) { state = State.ACTIVE; } } else if (msg.type == MType.LOG) { if (state == State.ACTIVE) { log (( Log)msg ); } } else if (msg.type == MType.STOP) { if (state == State.ACTIVE) { state = State.NOTACTIVE; } } ◮ the differenfce may be non-obvious on such small example, but
it becomes cruicial for larger actors
Inter-thread collaboration 109/121 Message handling - State vs message centric
Which one is better?
◮ depends on the particular case, for example
S1 S2 S3 M1 e e e M2 a b M3 c
◮ message M1 should result in the same action for all states
◮ message-centric is better, because less code ◮ then M2 is handled in 2 states and M3 in 1 state
◮ mixing – combine both ways
◮ e.g. error message handling is a separate case, but the rest is
state-centric
Inter-thread collaboration 110/121 Message handling - State vs message centric
Methods as messages
rewrite message-centric case into separate methods, e.g.
public void startMsg () { send(new RunnableMessage (new Runnable () { public void run () { if (state == State.NOTACTIVE) { state = State.ACTIVE; } } })); } ◮ nicer call syntax, as if method calls ◮ cumbersome handler syntax ◮ loosing ability to do state-centric message handling
Swing is a sort of message-centric handling, however without explicit methods.
Inter-thread collaboration 111/121 Message handling - Inboxes
Message guards and priorities
Inbox is a message queue with more sophisticated message handling (idea from Erlang):
◮ guards – apply additional constraints on what messages are
handled
◮ e.g. do not print duplicates: if(lastText!=msg.text) ◮ coneptually nothing new, just another condition on message
handling
◮ priorities – as with priority queues, messages are not handled in
FIFO order
◮ e.g. START/STOP messages may have higher priority than
LOG
◮ implement with priority queue or 2 queues and own
synchronizer
Inter-thread collaboration 112/121 Message handling - Inboxes
Postponed delivery and timeout
Postponed delivery may have two meanings:
- 1. message is not discarded if cannot be handled right now, e.g.
◮ SEND(data) message during CONNECTING phase ◮ CONNECT message during DISCONNECTING phase
- 2. message delivery is scheduled in the future
◮ CONNECT is scheduled in 5 seconds after DISCONNECTED
event
Timeout is set when waiting for a new message in the queue
◮ if matching message has not arrived – execute special code ◮ e.g. waiting for AUTH_SUCCESSFUL for 5 seconds from a
child actor
◮ non-matched messages may be left in the queue
Make sure actor state is not accessed from timer thread directly!
Inter-thread collaboration 113/121 Reasoning with actors -
Outline
Inter-thread collaboration Actor model Message handling
State vs message centric Inboxes
Reasoning with actors Actor frameworks
Inter-thread collaboration 114/121 Reasoning with actors -
General scheme
Two levels to think about actor behavior:
- 1. Validate each actor as autonomous entity, separatly from other
- actors. Validate the actor is in consisten state all the time, e.g.
◮ connection actor who is running disconnection procedure ◮ actor receives new CONNECT message (from user click or
some re-connect logic)
◮ can actor interrupt disconnection procedure? ◮ should CONNECT message be postponed or discarded? ◮ see state diagram on the next slide
- 2. Validate orchestration of actors
◮ How actors collaborate? what messages can be sent from one
actor to another.
◮ Is it possible that some message is not delivered? Are timeouts
set up for such cases?
◮ Supervision – hierarchy of actors, parent receives notifications
about its child
Inter-thread collaboration 115/121 Reasoning with actors -
Actor (component) diagrams
Show what messages actors may send to each other:
SwingClient ProximityService TravelerStorage
Update(Listtrav)
Connection
Recvtrav Recv(Collectiontrav) Connect,Send(x) Connected,Disconnected Recv(trav) Connect
◮ Connection actor may request delayed Connect to itself ◮ ProximityService queue contains 0 or 1 Collection message of
travelers
◮ collection is updated with every new traveler: aggregate queue
Inter-thread collaboration 116/121 Reasoning with actors -
State diagrams
◮ state transition scheme:
<message> <guards>
- <actions>
UNCONNECTED CONNECTED ERROR
Connect socket.connect() ok
- dispatcher.start()
ALL!Connected Send(x) socket ok
- socket.send(x)
DISCONNECTED
Send(x) socket bad
- Disconnected/ALL!Disconnected
Connect socket.connect() ok
- dispatcher.start()
ALL!Connected Connect socket.connect() bad
- Disconnected/ALL!Disconnected
◮ happens when <message> arrives and <guards> are satisfied ◮ then <actions> are executed as the result ◮ also <dest>!<message> means sending the message to
destination
Inter-thread collaboration 117/121 Reasoning with actors -
Actor with extra thread
◮ actor should not block its thread, because it must be
responsive
◮ IO may require blocking
◮ create extra thread and do IO ◮ deliver all messages to the actor ◮ accessing actor internal state is dangerous!
public void run () { try { while (! Thread. currentThread (). isInterrupted ()) { Message message = readMessage (); if (message == null) break; send(new Recv(message )); } } catch ( IOException e) { } finally { LOG.info("Dispatcher finished for "+socket ); send(new Disconnected ( Connection .this )); }
Inter-thread collaboration 118/121 Reasoning with actors -
Actor supervision
◮ Actors may be in the tree or graph hierarchy
◮ tree signifies child/parent actor relationships
◮ parent asks and controls child behavior (e.g. children for
connection establishment, authentication, ..)
◮ a child reports back to parent when it is finished ◮ supervisor actor (parent) is notified though message when its
child actor is lost/failed
◮ poison pill may be used to stop a child
◮ special message that the child understands as stop
Inter-thread collaboration 119/121 Actor frameworks -
Outline
Inter-thread collaboration Actor model Message handling
State vs message centric Inboxes
Reasoning with actors Actor frameworks
Inter-thread collaboration 120/121 Actor frameworks -
Akka framework
akka.io
Inter-thread collaboration 121/121 Actor frameworks -
Summary
◮ locking help can be escaped by using thread communication
and collaboration techniques
◮ producer/consumer and actors ◮ locks are only applied for queues, no deadlock possibility