Java Synchronization
Java Synchronization Java uses the concept of monitors Java uses the concept that every object has a lock
synchronized Statement
Every object has a lock associated with it.
Calling a synchronized method attempts to possess the lock If no one owns the lock, then this thread has/owns the lock.
If a calling thread does not own the lock (another thread already owns it), the calling thread is placed in the entry set for the objects lock.
The lock is released when a thread exits the synchronized method.
Entry Set
synchronized enter() Method
public synchronized void enter(Object item) {
while (count == BUFFER_SIZE) Thread.yield(); ++count; buffer[in] = item; in = (in + 1) % BUFFER_SIZE; }
synchronized remove() Method
public synchronized Object remove() {
Object item; while (count == 0) Thread.yield(); --count; item = buffer[out]; out = (out + 1) % BUFFER_SIZE;
return item;
}
The wait() Method
When a thread calls wait(), the following occurs:
- the thread releases the object lock. - thread state is set to blocked. - thread is placed in the wait set.
Entry and Wait Sets
The notify() Method
When a thread calls notify(), the following occurs:
- selects an arbitrary thread T from the wait set. - moves T to the entry set. - sets T to Runnable.
T can now compete for the objects lock again.
enter() with wait/notify Methods
public synchronized void enter(Object item) {
while (count == BUFFER_SIZE) try { wait(); } catch (InterruptedException e) { } } ++count; buffer[in] = item; in = (in + 1) % BUFFER_SIZE; notify(); }
remove() with wait/notify Methods
public synchronized Object remove() {
Object item; while (count == 0) try { wait(); } catch (InterruptedException e) { } --count; item = buffer[out]; out = (out + 1) % BUFFER_SIZE; notify(); return item; }
Multiple Notifications
notify() selects an arbitrary thread from the wait set. *This may not be the thread that you want to be selected.
Java does not allow you to specify the thread to be selected. notifyAll() removes ALL threads from the wait set and places them in the entry set. This allows the threads to decide among themselves who should proceed next. notifyAll() is a conservative strategy that works best when multiple threads may be in the wait set.
Reader Methods with Java Synchronization
public class Database { public Database() { readerCount = 0; dbReading = false; dbWriting = false; } public synchronized int startRead() { /* see next slides */ } public synchronized int endRead() { /* see next slides */ } public synchronized void startWrite() { /* see next slides */ } public synchronized void endWrite() { /* see next slides */ } private int readerCount; private boolean dbReading; private boolean dbWriting;
}
startRead() Method
public synchronized int startRead() {
while (dbWriting == true) { try { wait(); } catch (InterruptedException e) { } } ++readerCount; if (readerCount == 1) dbReading = true; return readerCount; }
endRead() Method
public synchronized int endRead() {
--readerCount if (readerCount == 0) db.notifyAll(); return readerCount; }
Writer Methods
public void startWrite() {
while (dbReading == true || dbWriting == true) try { wait(); } catch (InterruptedException e) { } dbWriting = true; } public void endWrite() { dbWriting = false; notifyAll();
Block Synchronization
Blocks of code rather than entire methods may be declared as synchronized.
This yields a lock scope that is typically smaller than a synchronized method.
Block Synchronization (cont)
Object mutexLock = new Object();
... public void someMethod() { // non-critical section synchronized(mutexLock) { // critical section }
// non-critical section
}
2 types of monitors
Signal-and-continue Monitor Monitor that allows a thread to signal that the monitor is available, but does NOT require the thread (signaler) to release the lock until it exits the monitor, at which point a signaled thread may enter the monitor. (used by Java) Signal-and-exit Monitor Monitor that requires a thread to release the lock on the monitor as soon as the thread signals another thread. (signaler immediately leaves, then the signaled thread comes in.)
Java Semaphores
Java does not provide a semaphore, but a basic semaphore can be constructed using Java synchronization mechanism.
Semaphore Class
public class Semaphore {
public Semaphore() { value = 0; }
public Semaphore(int v) {
value = v; } public synchronized void P() { /* see next slide */ }
public synchronized void V() { /* see next slide */ }
private int value; }
P() Operation
public synchronized void P() {
while (value <= 0) { try { wait(); } catch (InterruptedException e) { } }
value --;
}
V() Operation
public synchronized void V() {
++value;
notify(); }