我正在編寫一個使用ReentrantLock
而不是生產者和消費者問題的小程序。但程序卡住了,因爲一旦生產的物品被消耗,消費者線程將停止並且不再恢復消耗。Java線程生產者和消費者
代碼片段:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Mantou2 {
int id;
public Mantou2(int id) {
this.id = id;
}}
class Basket2 {
final int max = 20;
Mantou2[] ms;
int n;
Lock lock;
Condition full;
Condition empty;
public Basket2() {
ms = new Mantou2[max];
n = 0;
lock = new ReentrantLock();
full = lock.newCondition();
empty = lock.newCondition();
}
public void consume() {
lock.lock();
try {
while (n == 0) {
System.out.println("No Mantou left!");
empty.await();
}
empty.signal();
System.out.println(ms[--n].id + " consumed and " + n + " left");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void produce() {
lock.lock();
try {
while (n == max) {
System.out.println("Inventory is full!");
full.await();
}
full.signal();
ms[n] = new Mantou2(n++);
System.out.println(ms[n - 1].id + " produced and " + n + " left");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}}
class Consumer2 implements Runnable {
Basket2 basket;
public Consumer2(Basket2 basket) {
this.basket = basket;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 50; i++) {
basket.consume();
try {
Thread.sleep((long) (Math.random() * 300));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}}
class Producer2 implements Runnable {
Basket2 basket;
public Producer2(Basket2 basket) {
this.basket = basket;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 50; i++) {
basket.produce();
try {
Thread.sleep((long) (Math.random() * 300));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}}
public class ProducerCustomer2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Basket2 basket = new Basket2();
Producer2 producer = new Producer2(basket);
Consumer2 consumer = new Consumer2(basket);
Thread p = new Thread(producer);
Thread c = new Thread(consumer);
p.start();
c.start();
}}
我認爲你應該多調試一下,如果你能夠更具體地瞭解你所面臨的問題,那將會很棒。 –
如何調試:https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ –
[BlockingQueue](https://docs.oracle.com/javase/8/docs/ api/java/util/concurrent/BlockingQueue.html)會讓你的生活更輕鬆。 –