Reputation: 1025
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
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