Synchronization
Synchronization
Synchronization
This material is based on the operating system books by Silberschatz and Stallings
and other Linux and system programming books.
Operating Systems, CSE Dept., Qatar University
Objectives
Motivations
Concurrent Programming
Producer/Consumer Problem
Synchronization Terminology
Cooperative Processes Interaction Structure
Java Synchronization
Java Object locking (Synchronized Access)
Using yield,
Using wait/notify and wait/notifyAll methods pairs
process.
unbounded-buffer places no Buffer
practical limit on the size of
the buffer.
remove()
bounded-buffer assumes that
there is a fixed buffer size. Consumer
BoundedBuffer<class> UnBoundedBuffer<class>
public Producer(Buffer b) {
buffer = b;
}
}
Operating Systems, CSE Dept., Qatar University
The Consumer
import java.util.*;
public class Consumer implements Runnable {
private Buffer buffer;
public Consumer(Buffer b) {
buffer = b;
}
}
Operating Systems, CSE Dept., Qatar University
The Factory Class
public Factory(){
Buffer buffer = new BoundedBuffer();
Thread producerThread = new Thread(new Producer(buffer));
Thread consumerThread = new Thread(new Consumer(buffer));
producerThread.start();
consumerThread.start();
}
....
Entry Section - Code that requests permission to enter its critical section.
Exit Section - Code that runs after exiting the critical section
Threads waiting to acquire the object lock are placed in the entry set for the
object lock.
foo() {
synchronized (this) { …code… }
}
}
}
Operating Systems, CSE Dept., Qatar University
Locks in Java
Properties:
No other thread can get lock on x while in block
Locked block of code critical section
Avoiding deadlock
Potential problem:
Threads holding lock may be unable to obtain lock held by other
thread, and vice versa
Thread holding lock may be waiting for action performed by
other thread waiting for lock
Program is unable to continue execution (deadlock)
If the wait set of an object is empty, then the call for notify() or
notifyall() has no effect.
Usage of Semaphores
In a multiprocessor System where locks are expected to be held for short time –
critical section is short -, busy wait is useful requiring no context switching.
But in most applications, locks are expected to be held for long time – critical
section is long – So, this implementation is not good.
Two operations:
block – place the process invoking the operation on the
appropriate waiting queue.
wakeup – remove one of processes in the waiting queue
and place it in the ready queue.
P0 P1
Waits for Waits for
S.acquire(); Q.acquire(); P0 to
P1 to
release Q. Q.acquire(); S.acquire(); release S.
. .
. .
. .
S.release(); Q.release();
Q.release(); S.release();
•Semaphore mutex
initialized to the value 1
•Semaphore full
initialized to the value 0.
•Semaphore empty
initialized to the value N.
public Database() {
readerCount = 0;
mutex = new Semaphore(1);
db = new Semaphore(1);
}
db.acquire();
System.out.println("writer " + writerNum + " is
writing.");
How to?
import java.util.concurrent.locks.ReentrantLock;
Usage:
lock key = new ReentrantLock();
key.lock();
try{
//critical section
}
finally{
key.unlock();
}