Download presentation
Presentation is loading. Please wait.
Published byDominic Pierce Modified over 9 years ago
1
SPL/2010 Synchronization 1
2
SPL/2010 Overview ● synchronization mechanisms in modern RTEs ● concurrency issues ● places where synchronization is needed ● structural ways (design patterns) for exclusive access 2
3
SPL/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
4
SPL/2010 Java Synchronization - concurrent objects safety ● threads which access the same object concurrently. ● safety - synchronize access to internal state of the object 4
5
SPL/2010 class Even 5
6
SPL/2010 ● if threads can access internal state of object concurrently - not safe ● @invariant is not guaranteed ● code perfectly safe in sequential environment 6
7
SPL/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
8
SPL/2010 8
9
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
10
SPL/2010 anonymous class - class that has no name ● Rules: ● always extend a super class or implement an interface ● implement all abstract methods in super class or interface. ● uses default constructor from the super class to create an instance 10
11
SPL/2010 Inlining 11
12
SPL/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
13
SPL/2010 13
14
SPL/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
15
SPL/2010 Re-ordering ● compiler must be able to re-order simple instructions to optimize our code 15
16
SPL/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
17
SPL/2010 Re-ordering ● in concurrent environments, reordering may harm 17
18
SPL/2010 “must-happen-before” ● compiler would not reorder if "must-happen- before" constraint 18
19
SPL/2010 “must-happen-before” ● "must-happen-before“ - call to any (non- inline) function ● compiler would not go recursively into that function 19
20
SPL/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
21
SPL/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
22
SPL/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
23
SPL/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
24
SPL/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
25
SPL/2010 synchronized ● each thread, calling the method, must first acquire lock. ● when thread exits – thread releases lock 25
26
SPL/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
27
SPL/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
28
SPL/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
29
SPL/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
30
SPL/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
31
SPL/2010 Locks are Reentrant 31
32
SPL/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
33
SPL/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
34
SPL/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 available 34
35
SPL/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
36
SPL/2010 36
37
SPL/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
38
SPL/2010 Not thread safe 38
39
SPL/2010 Another solution? 39
40
SPL/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
41
SPL/2010 Design Patterns to Enforce Safety ● Composition / Client Side Locking 41
42
SPL/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
43
SPL/2010 Composition / Containment ● wrapper around Vector class: ● Enforces right synchronization policy ● Delegates all calls (after synchronization is verified) to underlying implementation class. 43
44
SPL/2010 44
45
SPL/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
46
SPL/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
47
SPL/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
48
SPL/2010 Client side locking ● only when we know internal implementation ● Vector uses monitor ● not when unknown internal implementation ● not when implementation may change 48
49
SPL/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
50
SPL/2010 Version Iterators ● Iterators and Generics ● casting is bad - introduces clutter ● programmer knows what kind of data ● run time error – if wrong cast 50
51
SPL/2010 Generics ● programmers express intent ● restrict a list to contain a particular data type 51
52
SPL/2010 List, Iterator interfaces ( java.util ) 52
53
SPL/2010 Type parameters ● <> - declarations of type parameters for List and Iterator interfaces ● used in declaration, instead ordinary types ● when used with actual type all occurrences of formal type parameter are replaced by Integer 53
54
SPL/2010 Version iterators ● process Vector of Integers one at a time 54
55
SPL/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
56
SPL/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
57
SPL/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
58
SPL/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
59
SPL/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
60
SPL/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
61
SPL/2010 61
62
SPL/2010 62 Code-block synchronized version
63
SPL/2010 Synchronized methods and blocks synchronized void f() { /* body */ } is equivalent to: void f() { synchronized(this) { /* body */ } } 63
64
SPL/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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.