Tests

Mid Term Exam (PDF)

Some solutions:

Q3. The ResourceLock class does not have condition synchronization so many threads will be able to acquire the lock and use the resource even if we make the methods synchronized. We need to block other threads once the lock has been acquired

public class ResourceLock { //for controlling access to one resource only
    private boolean taken = false;
 
    //acquire the lock
    public synchronized void acquireLock() throws InterruptedException {
        while (taken == true)
            wait();
        taken = true; 
    }
 
    //release the lock
    public synchronized void releaseLock() { 
        taken = false;
        notifyAll();
    }
}

A solution using semaphore is also possible:

public class ResourceLock { //for controlling access to one resource only
    private Semaphore rlock = new Semaphore(1); //since there is one resource only
 
    //acquire the lock
    public void acquireLock() {
             rlock.down()
    }
 
    //release the lock
    public void releaseLock() { 
        rlock.up()
    }
}

Q4. UnBoundedBuffer

The first solution uses explicit condition variable for track both items where are put and items which are taken.

import java.util.*;
public class UnBoundedBuffer {
    private ArrayList buffer = new ArrayList();//to buffer items
    private int itemCount = 0;
    private int takeCount = 0;
 
    /**
     * put() is called by Producer thread
     */
    public synchronized void put(Object o) throws InterruptedException {
        while (itemCount == 10)
            wait();
        itemCount++;
        buffer.add(o);
        if (itemCount == 10) {
            takeCount = 0; //reset takeCount before notifying Consumer
            notify();
        }
    }
 
    /**
     * take() is called by Consumer thread
     */
    public synchronized Object take() throws InterruptedException {
        while(buffer.size() == 0 || takeCount == 10)
            wait();
        takeCount++;
        Object temp = buffer.remove(0); //remove first item
        if (takeCount == 10) {
            itemCount = 0; //reset takeCount before notifying Producer
            notify();
        }
        return temp;
    }
}

Another solution:

import java.util.*;
public class UnBoundedBuffer2 {
    private ArrayList buffer = new ArrayList();//to buffer items
 
    /**
     * put() is called by Producer thread
     */
    public synchronized void put(Object o) throws InterruptedException {
        while (buffer.size() == 10)
            wait();
        buffer.add(o);
        if (buffer.size() == 10) {
            notify();
        }
    }
 
    /**
     * take() is called by Consumer thread
     */
    public synchronized Object take() throws InterruptedException {
        while(buffer.size() == 0)
            wait();
        Object temp = buffer.remove(0); //remove first item
        if (buffer.size() == 0) {
            notify();
        }
        return temp;
    }
}

One more solution possible using turn and count/buffer.size()

Q5. Fair database with alternate turn for readers and writers

/**
 * This database implementation is fair to both the writers and 
 * writers by using alternating turns
 */
public class AlternatingTurnsDB implements IDatabase {
 
    private boolean writing = false;
    private boolean writersTurn = false;
    private int readerCount = 0;
 
    //reader methods
    public synchronized void startRead() {
        while (writing || writersTurn || readerCount == 1) {
            try {
                wait();
            }catch (InterruptedException iex) {}
        }
        readerCount++;
    }
 
    public synchronized void endRead() {
        readerCount--;
        writersTurn = true;
        notifyAll();
    }
 
    //writer methods
    public synchronized void startWrite() {
        while(writing || !writersTurn) {
            try {
                wait();
            } catch (InterruptedException iex) { }
        }
 
        writing = true;
    }
 
    public synchronized void endWrite() {
        writing = false;
        writersTurn = false;
        notifyAll();
    }
}