我使用可重入锁和条件编写了一个生产者消费者程序。它工作正常,但我不太确定实施是否正确。此外,它似乎不是最优的。有人可以验证这是否是一个正确的实现,而且你能告诉我如何优化它,比如 - 在真正需要的地方锁定
public class TestRL {
static class Observed {
boolean filled = false;
public void setFilled(boolean filled) {
this.filled = filled;
}
public boolean getFilled() {
return filled;
}
}
static Observed observed = new Observed();
static class Consumer implements Runnable {
Observed observed;
ReentrantLock lock;
Condition condition;
Consumer(Observed observed, ReentrantLock lock, Condition condition) {
this.observed = observed;
this.lock = lock;
this.condition = condition;
}
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 20; i++) {
if (observed.getFilled() == false) {
try {
System.out.println("consumer waiting");
condition.await();
System.out.println("consumed");
Thread.sleep(400 + 1000 * i % 2);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
observed.setFilled(false);
condition.signalAll();
}else{
observed.setFilled(false);
condition.signalAll();
}
}
} finally {
lock.unlock();
}
}
}
static class Producer implements Runnable {
Observed observed;
ReentrantLock lock;
Condition condition;
Producer(Observed observed, ReentrantLock lock, Condition condition) {
this.observed = observed;
this.lock = lock;
this.condition = condition;
}
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 20; i++) {
if (observed.getFilled() == true) {
try {
System.out.println("producer waiting");
condition.await();
System.out.println("produced");
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
observed.setFilled(true);
condition.signalAll();
}else{
observed.setFilled(true);
condition.signalAll();
}
}
} finally {
lock.unlock();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Producer producer = new Producer(observed, lock, condition);
Consumer consumer = new Consumer(observed, lock, condition);
Thread t1 = new Thread(producer);
Thread t2 = new Thread(consumer);
t1.start();
t2.start();
}
}