生产者&消费者咋出现死锁,牛人知道吗?
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
*
* @author Administrator 生产者消费者实例
*/
public class ProducerAndCustomer {
private static Buffer buffer = new Buffer(); // 内部类,用于缓冲生产的商品数
public static void main(String args[]) {
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new buyTask());
//executor.execute(new buyTask());
executor.execute(new produceTask());
//executor.execute(new produceTask());
executor.shutdown();
// System.out.println( (int)((Math.random() * 10) + 1));
}
// 执行消费者的任务
private static class buyTask implements Runnable {
@Override
public void run() {
while (true) {
buffer.buy((int) ((Math.random() * 10) + 1));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
// 执行生产者的任务
private static class produceTask implements Runnable {
@Override
public void run() {
while (true) {
buffer.produce((int) ((Math.random() * 10) + 1));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
// 内部类,用于缓冲生产的商品数
public static class Buffer {
int maxNumber = 20; // 缓冲区的最大容量
private static int proNumber = 0; // 当前缓冲区的容量,为了方便,直接用整数表示
private static Lock lock = new ReentrantLock();
private static Condition notFull = lock.newCondition();
private static Condition notEmpty = lock.newCondition();
public void produce(int amount) { // 生产者的方法
lock.lock();
try {
while (proNumber == maxNumber || proNumber + amount >= maxNumber) {
System.out.println("wait for the not full condition");
notFull.await(); // 调试时这句使线程等待的语句不起作用
}
proNumber += amount;
System.out.println("produce amount :" + amount + " for the proNumber:" + proNumber);
notEmpty.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void buy(int amount) // 消费者的方法
{
lock.lock();
try {
while (proNumber == 0 || proNumber - amount <= 0) {
System.out.println("wait for the not Empty condition");
notEmpty.await();
}
proNumber -= amount;
System.out.println("buy for the amount:" + amount + "and the proNumber " + proNumber);
notFull.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
console:
buy for the amount:7and the proNumber 5
produce amount :2 for the proNumber:7
buy for the amount:6and the proNumber 1
wait for the not Empty condition
produce amount :3 for the proNumber:4
wait for the not Empty condition
produce amount :4 for the proNumber:8
wait for the not Empty condition
produce amount :6 for the proNumber:14
buy for the amount:9and the proNumber 5
buy for the amount:2and the proNumber 3
produce amount :2 for the proNumber:5
buy for the amount:4and the proNumber 1
produce amount :9 for the proNumber:10
buy for the amount:7and the proNumber 3
produce amount :4 for the proNumber:7
buy for the amount:1and the proNumber 6
produce amount :10 for the proNumber:16
wait for the not full condition
buy for the amount:6and the proNumber 10
wait for the not full condition
wait for the not Empty condition