Mutual Exclusion and Synchronization in Java
by Dan Ford


Listing One
import java.util.Date;
class MyThread extends Thread {
    public void run() {
        while (true) {
            System.out.println("It is now " + new Date());
            try {
                Thread.sleep(1000); // sleep for 1 second
            } catch (InterruptedException e) { }
        }
    }
}
class MyApp {
    public static void main (String args[]) {
        MyThread thrd = new MyThread();
        thrd.start();
        try {
            Thread.sleep(10000);    // sleep for 10 seconds
        } catch (InterruptedException e) { }
        thrd.stop();
        System.exit(0);
    }
}

Listing Two

 ...
public synchronized void incrementCounter() { this.counter++; }
 ...

Listing Three
 ...
public void incrementCounter() { 
synchronized(this) { this.counter++; }
}
 ...

Listing Four
 ...
public void setName(StringBuffer name) { 
    synchronized(this) {
        synchronized(name) { 
            this.myname = new String(name);
        } 
    }
}
 ...


Listing Five
abstract class BaseMutex {
    public BaseMutex(boolean bManual, boolean binitSignaled) {
        this.bSignaled = binitSignaled;
        this.bAuto = !bManual;
    }
    protected synchronized int waitForSingleObject(long ulTimeout) {
        if (bSignaled) {
            if (bAuto)
                reset();
            return Blockable.SUCCESS;
        }
        long t1, t2;
        try {
            t1 = System.currentTimeMillis();
            wait(ulTimeout);
            t2 = System.currentTimeMillis() - t1;
        } catch (InterruptedException e) {
            return Blockable.INTERRUPT;
        }
        if (t2 >= ulTimeout)
            return Blockable.TIMEOUT;
        if (bAuto)
            reset();
        return Blockable.SUCCESS;
    }
    protected synchronized void signal() {
        bSignaled = true;
        if (bAuto)
            notify();
        else
            notifyAll();
    }
    protected synchronized void reset() {
        bSignaled = false;
    }
    //----------------------------------------------
    boolean bSignaled;
    boolean bAuto;
}


Listing Six
class Mutex extends BaseMutex implements Blockable {
    public Mutex(boolean bInitialOwner) {
        super(false, !bInitialOwner);
        if (bInitialOwner) {
            count = 1;
            thrd = Thread.currentThread();
        } else {
            count = 0;
            thrd = null;
        }
    }
    public int waitForSingleObject() {
        return this.waitForSingleObject(INFINITE);
    }
    public synchronized int waitForSingleObject(long ulTimeout) {
        // if the mutex is not owned by any other thread
        if (count == 0) {
            count = 1;
            thrd = Thread.currentThread();
            return super.waitForSingleObject(ulTimeout);
        }
        // Otherwise, check to see if the current owner is the same thread 
        // calling now; if so, grant immediate access
        if (thrd == Thread.currentThread()) {
            count++;
            return SUCCESS;
        }
        // Otherwise block and wait for the current owner to relinquish mutex
        int rc = super.waitForSingleObject(ulTimeout);
        if (rc == SUCCESS) {
            count = 1;
            thrd = Thread.currentThread();
        }
        return rc;
    }
    public synchronized int releaseMutex() {
        if (thrd != null)
            if (thrd == Thread.currentThread()) {
                count--;
                if (count == 0) {
                    thrd = null;
                    super.signal();
                }
                return SUCCESS;
            }
        return NOTOWNED;
    }
    // private data members
    private int    count;
    private Thread thrd;
}


Listing Seven
class CriticalSection extends BaseMutex {
    public CriticalSection() {
        super(false, true);
    }
    public synchronized void enterCriticalSection() {
        while (waitForSingleObject(Blockable.INFINITE) != Blockable.SUCCESS) ;
    }
    public synchronized void leaveCriticalSection() {
        signal();
    }
}

Listing Eight
class MtxEvent extends BaseMutex implements Blockable {
    public MtxEvent(boolean bManual, boolean bSignaled) {
        super(bManual, bSignaled);
    }
    public int waitForSingleObject() {
        return super.waitForSingleObject(INFINITE);
    }
    public synchronized int waitForSingleObject(long ulTimeout) {
        return super.waitForSingleObject(ulTimeout);
    }
    public synchronized void setEvent() {
        signal();
    }
    public synchronized void resetEvent() {
        reset();
    }
    public synchronized void pulseEvent() {
        signal();
        reset();
    }
}


Listing Nine
class Semaphore implements Blockable {
    public static final int INVALID_INCREMENT = -1;
    
    public Semaphore(int initialValue, int maxValue) {
        currentLocks = initialValue;
        maxLocks = maxValue;
    }
    public int waitForSingleObject() {
        return this.waitForSingleObject(INFINITE);
    }
    public synchronized int waitForSingleObject(long ulTimeout) {
        long t1, t2;
        if (currentLocks == maxLocks) {
            try {
                t1 = System.currentTimeMillis();
                wait(ulTimeout);
                t2 = System.currentTimeMillis() - t1;
                if (t2 >= ulTimeout)
                    return TIMEOUT;
            } catch (InterruptedException e) {
                return INTERRUPT;
            }
        }
        currentLocks++;
        return SUCCESS;
    }
    public synchronized int releaseSemaphore(int increment) {
        if (currentLocks - increment >= 0) {
            currentLocks -= increment;
            for (int i=0; i < increment; i++)
                notify();
            return SUCCESS;
        }
        return INVALID_INCREMENT;
    }
    // private data members
    private int currentLocks;
    private int maxLocks;
}

