Title: Concurrency Problems
1Concurrency Problems
- Explain the following concurrency problems
- Deadlock Reader/Writer
- Evaluate methods for handling deadlock
- Explain a java solution to reader/writer problem
- References
- www.javaworld.com/javaworld/jw-09-1998/jw-09-thre
ads.html - www.javaworld.com/javaworld/jw-10-1998/jw-10-tool
box.html - www.javaworld.com/javaworld/jw-07-2000/jw-0714-lo
cks.html - www.javaworld.com/javaworld/jw-10-2001/jw-1012-de
adlock.html
2Deadlock
- A group of threads that cant proceed
- Each thread is holding a resource
- Each thread needs a resource held by another one
- No thread will give up a resource
- Why is it a difficult problem?
- It will occur intermittently
- Depends on random occurrences of events
- Different timing it wont occur
- Difficult to debug
- Try to design deadlock out of the system
Thread 1
Thread 2
Resource 1
Resource 2
Resource 3
Thread 3
3Conditions for deadlock
- Deadlock occurs when the following are true
- Mutual exclusion
- Resources cant be shared
- Hold and wait
- Keep resources when requesting others
- No pre-emption
- Resources only given up voluntarily
- Circular wait
- Several threads form a circular chain where each
waits for a resource held by the next one - Preventing one of these prevents deadlock
If they can be shared, a thread cant be blocked
waiting
If no resources are held, cant block someone
else
Forcibly free resources to break circle
No circular chain no deadlock
4Designing Deadlock out
- Which condition do the following rules prevent?
- Must request all resources at one time
- Resources numbered, must request in order
- Dont allocate resources if deadlock is possible
- Release all resources before requesting more
- Use a printer manager to store and print output
- Detect deadlock, take resources back
Mutual exclusion Hold and wait No
pre-emption Circular wait
5Problems
- What are the problems with the following rules?
- Request all resources at one time
- Resources numbered, must request in order
- Dont allocate resources if deadlock is possible
- Release all resources before requesting more
- Use a printer manager to store and print output
- Detect deadlock, take resources back
Inefficient Resource Use
Complex Centralised Algorithm
Not always Possible
6A Reasonable, Practical Solution
- Only access resources in a fixed order
- Each resource has a number
- Cant request a resource if you hold a higher
numbered one - Disadvantages
- May request resources long before theyre used
- Advantages
- Simple
- No need for a centralised manager
7Reader / Writer A Standard Problem
- Requirements
- A shared resource
- Writer Threads
- Modify the resource
- Must have exclusive access
- Reader Threads
- Access but dont change the resource
- Many Readers access the resource simultaneously
- Examples
- Shared file
- Database access
8Solution with Semaphores
When readers are active
Semaphore
okToRead
Shared Resource
Active Readers
Waiting Writers
okToWrite
When a writer is active
Waiting Readers
okToRead
Shared Resource
Waiting Writers
Active Writer
okToWrite
9Solution with semaphores Readers
- mutex.wait()
- if ((activeWriterswaitWriters) 0)
- okToRead.signal()
- activeReaders
- else
- waitReaders
-
- mutex.signal()
- okToRead.wait()
- // read the data
- mutex.wait()
- activeReaders--
- if((activeReaders 0) (waitWriters gt 0))
- okToWrite.signal()
- activeWriters
- waitWriters--
-
Signal okToRead if access is to be allowed.
How does this work think about it carefully
Mutual exclusion on the lock data structure
is ensured by mutex. What is the initial value?
Held up here if a writer is already in the region.
Allow one of the waiting writers to progress
10Solution with semaphores Writers
- mutex.wait()
- if ((activeWriters activeReaders
waitWriters) 0) - okToWrite.signal()
- activeWriters
- else
- waitWriters
- mutex.signal()
- okToWrite.wait()
- // --write the necessary data--
- mutex.wait()
- activeWriters --
- if (waitWritersgt0)
- okToWrite.signal()
- activeWriters
- waitWriters--
- else
- while (waitReaders gt0)
What is this for?
How does this work think about it very
carefully
How is mutual exclusion achieved?
What does this do?
What are the initial values of the
semaphores? mutex okToWrite okToRead
Why use a while loop here?
11Basic Java Solution Overview
When readers are active
Why are these waiting?
ReadWriteLocks lock
Shared Resource
Waiting Readers
Active Readers
Lock
Writers waiting on own lock
What is a fair system?
When a writer is active
ReadWriteLocks lock
Shared Resource
Waiting Readers
Active Writer
Writers waiting on own lock
12Basic Java Solution Overview
- Keep a count of the number of active readers
(activeReaders ) - If a writer requests access while readers or
writers are active, it waits - A new object is created, and the writer waits on
that objects lock. - The locks are queued up in a linked list
- If readers request access while a writer is
waiting, they are blocked until the current batch
of readers and the waiting writer have finished. - Keep a count of how many readers are waiting for
access. - Finishing readers call readAccomplished().
- When activeReaders is zero, the first queued
writer is released. - Finishing writers call writeAccomplished()
- This releases any waiting readers
- If no readers are waiting, the next writer in
line is released.
13Basic Java Solution Initialisation
- public class ReadWriteLock
- private int activeReaders 0
- private int waitingReaders 0
- private int activeWriters 0
- private final LinkedList writerLocks
- new LinkedList() // not threadsafe
- public ReadWriteLock()
-
What does not threadsafe mean?
14Basic Java Solution Readers Methods
- public synchronized void requestRead()
- if( activeWriters0 writerLocks.size()0
) - activeReaders
- else
- waitingReaders
- try wait() catch(InterruptedException
e) -
-
- public synchronized void readAccomplished()
- if( --activeReaders 0 )
- notifyWriters()
-
15Basic Java Solution Writers Methods 1
- public void requestWrite()
- // if synchronized could cause a
nested-monitor deadlock - Object lock new Object()
- synchronized( lock )
- synchronized( this )// Now synchronize on
this object - if(writerLocks.size()0
- activeReaders0
- activeWriters0)
- activeWriters
- return // jumps over the "wait" call
- // releases both lock
-
- writerLocks.addLast( lock )
-
- try lock.wait() catch(InterruptedExceptio
n e) - // can only wait if you hold the lock
-
16Basic Java Solution Writers Methods 1
- public synchronized void writeAccomplished()
- --activeWriters
- if( waitingReaders gt 0 ) // priority to
readers - notifyReaders()
- else
- notifyWriters()
-
-
17Nested Monitor Deadlock
- public void synchronized requestWrite()
- Object innerLock new Object()
- synchronized( innerLock )
- if( ltconditiongt)
- // do stuff
- return // jump over the "wait"
-
- // do stuff
- try innerLock.wait() catch(InterruptedExc
eption e) -
-
- All the methods that can release the innerLock
are also synchronized. - They cant run until requestWrite() is finished.
- requestWrite() cant finish until one of them
runs - We have a problem DEADLOCK
Note A monitor is a collection of
functions where only one of the functions can be
executed at a time. Monitors were invented long
before Java A Java object with synchronized
methods is a monitor.
18Basic Java Solution notifyXXX()
- private void notifyReaders()
- //must be called from a synchronized method
- activeReaders waitingReaders
- waitingReaders 0
- notifyAll()
-
- private void notifyWriters()
- //must be called from a synchronized method
- if( writerLocks.size() gt 0 )
- Object oldest writerLocks.removeFirst()
- activeWriters
- synchronized( oldest ) oldest.notify()
-
-
19Starvation Fairness
- Starvation
- A process gets no chance to progress
- Fairness
- Each thread gets a chance to make progress
- Are the reader/writer solutions fair?
- Could a writer to be kept waiting as a constant
stream of readers come and go so there is always
at least one active reader
20Livelock Deadlock
- Deadlock
- Two (or more) threads waiting for the other(s)
- Livelock
- Two (or more) threads running but unable to make
progress because of the other(s) - E.g. dining philosophers needing two forks
constantly picking up a fork on one side, not
being able to get the other, so dropping the
first fork and then trying to get the other. - E.g. two people blocking each other on a path
each moving side to side in synchronisation
21Summary
- Deadlock
- Gives rise to obscure, random errors
- Prevent by making one of 4 conditions impossible
- Preventing each condition has disadvantages
- Reader/Writer problem
- Common standard problem
- Solution with Java monitors (basic locks)
- Solution with semaphores
- These solutions are difficult
- Easy to make errors
- Are semaphores Java monitors too low level?