1 / 63

Synchronization

Synchronization. Overview. synchronization mechanisms in modern RTEs concurrency issues places where synchronization is needed structural ways (design patterns) for exclusive access. Overview. synchronization mechanism in Java RTE Visibility and re-ordering

quinto
Télécharger la présentation

Synchronization

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Synchronization

  2. Overview • synchronization mechanisms in modern RTEs • concurrency issues • places where synchronization is needed • structural ways (design patterns) for exclusive access

  3. 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.

  4. Java Synchronization - concurrent objects safety • threads which access the same object concurrently. • safety - synchronize access to internal state of the object

  5. class Even

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

  7. 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

  8. 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. Inlining

  10. 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

  11. 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

  12. Re-ordering • compiler must be able to re-order simple instructions to optimize our code

  13. Re-ordering • compiler guarantees safe reordering in non-concurrent execution environments. • order of operations is that the sequence will end with operation 4

  14. Re-ordering • in concurrent environments, reordering may harm

  15. “must-happen-before” • compiler would not reorder if "must-happen-before" constraint

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

  17. "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

  18. 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)

  19. 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

  20. 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

  21. locks • locks are in one of two states; • in possession of thread • 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

  22. synchronized • each thread, calling the method, must first acquire lock. • when thread exits – thread releases lock

  23. 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

  24. 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()

  25. When to Use Synchronization • invariant involving several members - synchronized with same lock. • never lock large parts of code. • minimize code sections which use locking

  26. 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.

  27. 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 */ }

  28. Locks are Reentrant

  29. 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.

  30. 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

  31. 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

  32. 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

  33. 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?

  34. Not thread safe

  35. Another solution?

  36. 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

  37. Design Patterns to Enforce Safety • Composition / Client Side Locking

  38. 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.

  39. Composition / Containment • wrapper around Vector class: • Enforces right synchronization policy • Delegates all calls (after synchronization is verified) to underlying implementation class.

  40. 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

  41. 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

  42. 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

  43. Client side locking • only when we know internal implementation • Vector uses monitor • not when unknown internal implementation • not when implementation may change

  44. 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

  45. Version Iterators • Iteratorsand Generics • casting is bad - introduces clutter • programmer knows what kind of data • run time error – if wrong cast

  46. Generics • programmers express intent • restrict a list to contain a particular data type

More Related