SPL/2010 Synchronization 1. SPL/2010 Overview ● synchronization mechanisms in modern RTEs ●...

Post on 17-Jan-2016

223 views 0 download

Transcript of SPL/2010 Synchronization 1. SPL/2010 Overview ● synchronization mechanisms in modern RTEs ●...

SPL/2010SPL/2010

Synchronization

1

SPL/2010SPL/2010

Overview

● synchronization mechanisms in modern RTEs

● concurrency issues● places where synchronization is needed

● structural ways (design patterns) for exclusive access

2

SPL/2010SPL/2010

Overview

● synchronization mechanism in Java RTE● Visibility and re-ordering● Design patterns to avoid safety issues:

● monitor pattern.● client side locking.● class composition.● version iterattor.

3

SPL/2010SPL/2010

Java Synchronization - concurrent objects safety

● threads which access the same object concurrently.

● safety - synchronize access to internal state of the object

4

SPL/2010SPL/2010

class Even

5

SPL/2010SPL/2010

● if threads can access internal state of object concurrently - not safe● @invariant is not guaranteed● code perfectly safe in sequential environment

6

SPL/2010SPL/2010

Visibility and Reordering – unsafe constructs in concurrent execution

● Visibility - when threads see values written to memory by other threads

● Reordering - compiler / RTE change code to optimize it

7

SPL/2010SPL/2010 8

SPL/2010SPL/2010

anonymous class - class that has no name

● combines class declaration and instance creation in one step in-line

● allows "on the fly" creation of object● reduce the number of .java files necessary● class used in specific situation: Comparator● compiler will create separate class files:

ClassName$SomeNumber.class

9

SPL/2010SPL/2010

Inlining

11

SPL/2010SPL/2010

Inlining

● Inline expansion - compiler optimization that replaces a function call site with the body of the callee.● improve time and space usage at runtime, at

cost of binary file size

12

SPL/2010SPL/2010 13

SPL/2010SPL/2010

output = 0

● thread t does not "see" the change to the state of d performed in main thread● thread main - implicitly created by JVM● executes main() method● main calls d.set(10): 10 is written to

memory: i_ member of: VisibilityDemo object ● t reads from i_ (d.get() )

– Java does not guarantee t sees most recent value written to this memory location

14

SPL/2010SPL/2010

Re-ordering

● compiler must be able to re-order simple instructions to optimize our code

15

SPL/2010SPL/2010

Re-ordering

● compiler guarantees safe reordering in non-concurrent execution environments.

● order of operations is that the sequence will end with operation 4

16

SPL/2010SPL/2010

Re-ordering

● in concurrent environments, reordering may harm

17

SPL/2010SPL/2010

“must-happen-before”

● compiler would not reorder if "must-happen-before" constraint

18

SPL/2010SPL/2010

“must-happen-before”

● "must-happen-before“ - call to any (non-inline) function ● compiler would not go recursively into that

function

19

SPL/2010SPL/2010

"synchronized" construct in Java

● allow only one thread at a time to enter a specific method of an object

● synchronized keyword to method's declaration

20

SPL/2010SPL/2010

synchronized

● Java coordinates actions of threads on object: ● keyword  before method name in class

definition:– public synchronized int add() - only one thread

is allowed to enter– constructors cannot be synchronized - syntax

error (only thread that creates an object access its constructor)

21

SPL/2010SPL/2010

synchronized

● Java RTE ensures that only one thread access this method.

● solves visibility and reordering problems; ● "write" to memory during synchronized code

section is guaranteed to be returned to all "read" operations following it

22

SPL/2010SPL/2010

How "synchronized" is implemented?

● Java mechanism - use it better / avoid common pitfalls● each object inside JVM (at runtime) has

a lock ("monitor") ● JVM maintain/initialize locks. ● cannot access locks explicitly● access implicitly using synchronized 

23

SPL/2010SPL/2010

locks

● locks are in one of two states;

1. in possession of thread

2. available● thread T tries to acquire the lock of any

object. ● if available – lock transferred to T possession ● otherwise, T sleeps (queue) until lock

available ● T wakes up and tries to acquire lock

24

SPL/2010SPL/2010

synchronized

● each thread, calling the method, must first acquire lock.

● when thread exits – thread releases lock

25

SPL/2010SPL/2010

The cost of locks – time, concurrency

● memory sync.: after thread exits – memory of all threads synchronize with main memory ● thread may cache copies of memory in its

own memory (e.g., CPU registers / CPU cache)

● blocking: threads must wait for each other

26

SPL/2010SPL/2010

When to Use Synchronization

● mutable variable accessible from different threads must be protected with lock ● else, you may be hit by re-ordering problems

● monitor pattern - internal state of object is encapsulated. ● objects are responsible to synchronize access

to state: synchronized get() /set() 

27

SPL/2010SPL/2010

When to Use Synchronization

● invariant involving several members - synchronized with same lock.

● never lock large parts of code. ● minimize code sections which use locking

28

SPL/2010SPL/2010

Synchronized Properties

● synchronized keyword is not part of the method signature.

● synchronized keyword cannot be specified in an interface.

● constructors cannot be  synchronized● no point - as long as constructor is not complete, object

instance is not accessible to other threads, unless…● static method as synchronized - lock associated with

the class to be used● (each class in Java is also an object on its own)

● Java locks are Reentrant: same thread holding the lock can get it again and again.

29

SPL/2010SPL/2010

Statics

● Access to static fields protected via synchronized static methods and blocks. Static synchronization employs the lock possessed by the Class object

● static lock for class C can also be accessed inside instance methods via:

synchronized(C.class) { /* body */ }

30

SPL/2010SPL/2010

Locks are Reentrant

31

SPL/2010SPL/2010

Locks are Reentrant/Recursive

● thread, T, acquired the lock of Even object ● in add() , T will be able to enter

doSomething()  - T already possesses lock of same object.

32

SPL/2010SPL/2010

● synchronized instance methods in subclasses employ the same lock as in their superclasses

● synchronization in an inner class method is independent of its outer class

33

SPL/2010SPL/2010

Locks are Reentrant/Recursive

● Reentrant locks are implemented using counter

● same thread may acquire lock multiple time, consecutively, without releasing

● each time the lock is acquired, an internal counter is incremented.

● lock is unavailable whenever counter > 1. ● when thread releases the lock, the counter value

is decremented by 1. ● when counter reaches 0, the lock is then

available34

SPL/2010SPL/2010

Locking a Specific Object

●  synchronized keyword to method declaration ● implicitly uses the lock of current object

● explicitly request to lock a specific object we wish to acquire● not advised to use synchronized blocks. It is

usually better to define synchronized methods

35

SPL/2010SPL/2010 36

SPL/2010SPL/2010

Vector: addIfAbsent()

● addIfAbsent()● new class – Vector hold some information● javadoc - Vector class is thread-safe● add an element only if missing

● Is it thread safe?

37

SPL/2010SPL/2010

Not thread safe

38

SPL/2010SPL/2010

Another solution?

39

SPL/2010SPL/2010

incorrect solution

● lock protecting addIfAbsent() may be different from lock protecting add()

● not sure that add() is synchronized ● implementation of Vector may change -

Vector can become not thread safe

40

SPL/2010SPL/2010

Design Patterns to Enforce Safety

● Composition / Client Side Locking

41

SPL/2010SPL/2010

Composition / Containment

● "almost" reimplementing the functionality of Vector. Why not extend Vector class and add the function we want? ● do not know how the class Vector protects

itself from concurrent access. ● do not know/not have access to, which

objects are used for synchronized access● good design strategy to have a basic (non

thread safe) object and a thread safe version of it.

42

SPL/2010SPL/2010

Composition / Containment

● wrapper around Vector class:● Enforces right synchronization policy● Delegates all calls (after synchronization is

verified) to underlying implementation class.

43

SPL/2010SPL/2010 44

SPL/2010SPL/2010

Composition / Containment

● we know exactly which lock is used to synchronize access to our vector.

● best applied in situations where: ● we are not sure/ do not know the internal

implementation of an object● implementation of object may change

without our knowledge

45

SPL/2010SPL/2010

● all methods are synchronized.● no public fields or encapsulation

violations.● methods are finite (no infinite loops or

unbounded recursion)● all fields are initialized to a consistent

state in constructors.● state of object is consistent

46

SPL/2010SPL/2010

Client Side Locking

● we may know the identity of the object which is used for synchronization● Vector class uses its own monitor (lock) to

achieve synchronization

47

SPL/2010SPL/2010

Client side locking

● only when we know internal implementation ● Vector uses monitor

● not when unknown internal implementation

● not when implementation may change

48

SPL/2010SPL/2010

Client side locking

● not OO: ● responsibility of synchronization to clients

instead of centralizing it in object● cannot ensure consistency among ALL clients

: – If client does not synchronize correctly, then ALL

the code will behave incorrectly.

● better to enforce safety on provider side

49

SPL/2010SPL/2010

Version Iterators

● Iterators and Generics

● casting is bad - introduces clutter ● programmer knows what kind of data ● run time error – if wrong cast

50

SPL/2010SPL/2010

Generics

● programmers express intent ● restrict a list to contain a particular data type

51

SPL/2010SPL/2010

List, Iterator interfaces (java.util)

52

SPL/2010SPL/2010

Type parameters <T>

● <> - declarations of type parameters for List and Iterator interfaces

● used in declaration, instead ordinary types

● when used with actual type <Integer> all occurrences of formal type parameter <E> are replaced by Integer

53

SPL/2010SPL/2010

Version iterators

● process Vector of Integers one at a time

54

SPL/2010SPL/2010

Concurrency problem

● consider  vec_ is shared by several threads, adding/removing elements concurrently. ● element pointed by iterator is deleted?● new element is added at the beginning ?

55

SPL/2010SPL/2010

Solution – synchronize loop

● synchronize iteration on vector● body of loop may be arbitrarily long - locking

the entire vector for the entire loop ● no access to object used to synchronize

56

SPL/2010SPL/2010

Solution - immutable

● create a temporary copy of vector● local to current thread● iterate over copy● inappropriate to copy the entire data

structure● need to lock the vector during copy

operation, – if vector class does not offer a thread-safe cloning

57

SPL/2010SPL/2010

Solution - fail-fast

● Vector iterators are fail-fast:● if element is added/removed after iterator

was created except through Iterator's remove or add ConcurrentModificationException is thrown.

58

SPL/2010SPL/2010

Solution - fail-fast

● useful for many readers few writers model

● fail-fast in java is on best-effort basis. ● fail-fast behavior of iterators in Java should

be used only to detect bugs.

59

SPL/2010SPL/2010

Version iterators

● Idea:● maintain version number that is incremented

upon each update to collection. ● iterator check value whenever asked for next

element and throw exception if changed● implementation of fail-fast iterators

60

SPL/2010SPL/2010 61

SPL/2010SPL/2010 62

Code-block synchronized version

SPL/2010SPL/2010

Synchronized methods and blocks

synchronized void f() { /* body */ }

is equivalent to:

void f() { synchronized(this) { /* body */ } }

63

SPL/2010SPL/2010

More Synchronization Primitives

● Lock interface ● test that a lock can be acquired without

blocking● tryLock() - returns if lock is not available ● Lock objects work like the implicit locks used

when accessing a synchronized code segment.

● Only one thread can own a Lock object at a time.

● Semaphore Exchanger Latch 64