Download presentation
Presentation is loading. Please wait.
Published byJessie Bond Modified over 9 years ago
1
Monitors and Blocking Synchronization Dalia Cohn Alperovich Based on “The Art of Multiprocessor Programming” by Herlihy & Shavit, chapter 8
2
Content 1. Introduction 2. Monitor Locks and Conditions 3. Readers-Writers Locks 4. Semaphores 5. Locks and Conditions – Example of Usage in Code
3
1. Introduction
4
Monitors Class Data Methods Monitor Data Methods Synchronization
5
Why do we need monitors? Thread AThread B Hey, are you full? Yes
6
Why do we need monitors? Thread AThread B Hey, are you empty? No
7
Why do we need monitors? Thread AThread B Hey, are you full? No
8
Why do we need monitors? Oskar doesn’t like questions!
9
Why do we need monitors? Thread AThread B
10
Why do we need monitors? Thread AThread B
11
Why do we need monitors? Thread AThread B
12
Why do we need monitors? No questions asked! Or: the internal state of the object was not exposed
13
2. Monitor Locks and Conditions
14
Monitor Locks A lock is a basic mechanism of ensuring mutual exclusion. Only one thread at a time can hold a lock. A thread acquires a lock when it first starts to hold the lock. A thread releases a lock when it stops holding the lock A monitor exports a collection of methods, each of which acquires the lock when it is called, and releases it when it returns.
15
Spin and Block If a thread can not immediately acquire a lock, it has two options: Spin – repeatedly testing whether the desired event had happened. Makes sense on a multiprocessor if we expect to wait for a short time (e.g. a thread waiting for another thread to release a lock). Keeps the processor busy without doing any work. Block – giving up the processor for a while to allow another thread to run. Makes sense if we expect to wait for a long or unpredicted time (e.g. dequeue an item from an empty buffer). Requires an expensive call to the operating system. A combination of the two is also possible
16
Conditions While a thread is waiting for something to happen to an object, it is a very good idea to release the lock on the object. After the waiting thread releases the lock, it needs a way to be notified when to reacquire the lock and try again. In Java concurrency package, the ability to release a lock temporarily is provided by a Condition object associated with a lock. In the example above: “The garbage can is empty”
17
The Lost-Wakeup Problem Instead of signaling “The garbage can is not empty” each time we throw an item to it, would it not be more efficient to signal the condition only when the can actually transmits from empty to non empty?
18
The Lost-Wakeup Problem Signal: I’m not empty!
19
The Lost-Wakeup Problem A situation where one or more threads wait forever without realizing that the condition had become true. Two simple programming practices that will minimize vulnerability: Always signal all processes waiting on a condition, not only one Specify a timeout when waiting.
20
Condition in Java newCondition() – creates a condition associated with a lock await() – releases the lock, gives up the processor, and later awaken and reacquire the lock signal() – awakes one waiting thread signalAll() – awakes all waiting threads
21
3. Readers-Writers Locks
22
Readers and Writers Readers – method calls which return information about the object’s state without modifying it Writers – method calls which actually modify the object. Many times there are much more readers than writers How can we use this property for optimization?
23
Example
24
Simple Readers-Writers Locks The two lock object satisfy following safety properties: No thread can acquire the write lock while any thread holds either the write lock or the read lock. No thread can acquire the read lock while any thread holds the write lock. Multiple threads may hold the read lock at the same time
25
Implementation A counter is used to keep track of the number of readers that have acquired the lock A Boolean field indicating whether a writer has acquired the lock
26
Simple Readers-Writers Locks What problem do we have?
27
Fair Readers-Writers Lock There are many possible ways to give the writers priority Example: FifoReadWriteLock This class ensures that once a writer calls the write lock’s lock() method, then no more readers will be able to acquire the read lock until the writer has acquired and released the write lock.
28
Implementation The class holds the following elements: readAcquires – counts the total number of read lock acquisitions. readReleases – counts the total number of read lock releases. A condition A private lock Each reader acquires the private lock: before incrementing readAcquires, and releasing it after it. While releasing the read lock, before it calls the associated condition’s signal() method if all readers have released their locks, and releasing it after it. Each writer reader acquires the private lock from the time they try to acquire the write lock and release after that release the write lock.
29
Simple Readers-Writers Locks
30
4. Semaphores
31
Semaphore - Origin One of the earliest forms of fixed railway signal is the semaphore. These signals display their different indications to train drivers by changing the angle of inclination of pivoted 'arms'. Semaphore signals were patented in the early 1840s.
32
Semaphores A Semaphore is a generalization of the mutual seclusion locks we describe earlier. Each Semaphore has a capacity c. Instead of allowing only one thread at a time into the critical section, it allows at most c threads.
33
Semaphore - Implementation The Semaphore itself is just a counter that keeps track on the number of thread that have been granted permission to enter the critical section. Provides two methods: A thread calls: acquire() to request permission to enter the critical section. If the call is about to exceed c, the calling thread is suspended until there is room. release() to announce that it is leaving the critical section. The call notifies a waiting thread that there is now room.
34
5. Locks and Conditions – Example of Usage in Code
35
Reentrant Lock In simple locks, a thread that attempts to reacquire a lock (during nested calls) it already holds will deadlock with itself. A lock is reentrant if it can be acquired multiple times by the same thread. We will implement a reentrant lock from a non-reentrant lock. In practice, the java.utils.concurrent.locks package provides reentrant lock classes.
36
Fields Definitions and C’tor The Owner field holds the ID of the last thread to acquire the lock The holdCount field is incremented each time the lock is acquired, and decremented each time it is released (the lock is free when the value is zero)
37
The Lock Method Acquires the internal lock. If the current thread is already the owner, it increments the hold count and returns. Otherwise, if the hold counter is not zero, the caller releases the lock and waits until the condition is signaled. When the caller awakens, it must still check that the hold count is zero. When the hold count is established to be zero, the calling thread makes itself the owner and sets the hold count to 1. Releases the internal lock.
38
The Unlock Method Acquires the internal lock. It throws an exception if either the lock is free, or the caller is not the owner. Otherwise, it decrements the hold counter. If the hold counter is zero, the caller signals the condition to wake up a waiting thread.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.