我写了一个并发的消费者和生产者计划。但是它是按顺序进行的:消费者只有在生产者无法生产后才开始消费;生产者只有在没有可供消费者消费的产品时才开始工作。它应该同时工作,因为在生产或消费产品之后,消费者/生产者将释放该锁并竞争获得该锁。
但是,其输出看起来像这样
Produced: 0
Produced: 1
Produced: 2
Produced: 3
Produced: 4
Queue is full Thread-0 is waiting , size: 5
Consumed: 0
Consumed: 1
Consumed: 2
Consumed: 3
Consumed: 4
Queue is empty Thread-1 is waiting , size: 0
Produced: 5
Produced: 6
Produced: 7
Produced: 8
Produced: 9
Queue is full Thread-0 is waiting , size: 5
Consumed: 5
Consumed: 6
Consumed: 7
Consumed: 8
Consumed: 9
我的程序如下:
消费者:
public class Consumer implements Runnable{
private final List<Integer> taskQueue;
public Consumer(List<Integer> stack) {
this.taskQueue = stack;
}
public void consume(){
synchronized (taskQueue){
while (taskQueue.isEmpty()){
try {
System.out.println("Queue is empty " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size());
taskQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Integer removeNum = taskQueue.remove(0);
System.out.println("consume " + removeNum);
taskQueue.notifyAll();
}
}
@Override
public void run() {
while (true){
consume();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
Consumer consumer = new Consumer(list);
Producer producer = new Producer(5, list);
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(consumer::run);
executorService.submit(producer::run);
}
}
制作人:
public class Producer implements Runnable {
private final Integer MAX_SIZE;
private final List<Integer> taskQueue;
public Producer(Integer MAX_SIZE, List<Integer> taskQueue) {
this.MAX_SIZE = MAX_SIZE;
this.taskQueue = taskQueue;
}
public void produce(int i){
synchronized (taskQueue){
while (taskQueue.size() == MAX_SIZE){
System.out.println("Task queue is full.");
try {
taskQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produce "+i);
taskQueue.add(i);
taskQueue.notifyAll();
}
}
@Override
public void run() {
int i = 1;
while (true){
produce(i++);
}
}
}