user1074896
user1074896

Reputation: 1025

What is advantage of locks over wait/notify?

What is advantage of locks over wait/notify? Code is very similar.

    private Object full = new Object();
private Object empty = new Object();

private Object data = null;

public static void main(String[] args) {
    Test test = new Test();
    new Thread(test.new Producer()).start();
    new Thread(test.new Consumer()).start();
}

public void push(Object d) {
    synchronized (full) {
        while (data != null)
            try {
                full.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }
    data = d;
    System.out.println("push");
    synchronized (empty) {
        if (data != null)
            empty.notify();
    }
}

public Object pop() {
    synchronized (empty) {
        while (data == null)
            try {
                empty.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }
    Object o = data;
    data = null;
    System.out.println("pop");
    synchronized (full) {
        if (data == null)
            full.notify();
    }
    return o;
}

class Producer implements Runnable {
    public void run() {
        while (true) {
            push(new Object());
        }
    }
}

class Consumer implements Runnable {
    public void run() {
        while (true) {
            pop();
        }
    }
}

and

    private final ReentrantLock lock = new ReentrantLock();
private final Condition fullState = lock.newCondition();
private final Condition emptyState = lock.newCondition();

private Object data = null;

public static void main(String[] args) {
    Test test = new Test();
    new Thread(test.new Producer()).start();
    new Thread(test.new Consumer()).start();
}

public void push(Object d) {
    lock.lock();
    try {
        while (data != null)
            try {
                fullState.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        data = d;
        System.out.println("push");
        emptyState.signal();
    } finally {
        lock.unlock();
    }
}

public Object pop() {
    Object result;
    lock.lock();
    try {
        while (data == null)
            try {
                emptyState.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        result = data;
        data = null;
        System.out.println("pop");
        fullState.signal();
    } finally {
        lock.unlock();
    }
    return result;
}

class Producer implements Runnable {
    public void run() {
        while (true) {
            push(new Object());
        }
    }
}

class Consumer implements Runnable {
    public void run() {
        while (true) {
            pop();
        }
    }
}

Upvotes: 0

Views: 1166

Answers (1)

aglassman
aglassman

Reputation: 2653

Check out the JavaDoc for ReeentratLock and your question will be answered.

"A reentrant mutual exclusion Lock with the same basic behavior and semantics as the implicit monitor lock accessed using synchronized methods and statements, but with extended capabilities."

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html

Upvotes: 4

Related Questions