【发布时间】:2019-02-04 13:55:34
【问题描述】:
我尝试为消费者创建 2 个线程,为生产者创建 2 个线程。 所有 4 个线程都在争用一种资源。 其中两个正在尝试从资源中消耗,其中两个正在尝试生产。
下面是代码
package com.threading;
import java.util.ArrayList;
import java.util.List;
public class TestConsumerProducer2 {
protected static int maxSize = 2;
static class Consumer implements Runnable {
List<Integer> goods;
public Consumer(List<Integer> goods) {
this.goods = goods;
}
public void consume() {
synchronized (goods) {
if (goods.size() <= 0) {
try {
goods.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " >>>> consuming >>>" + goods.remove(0));
goods.notifyAll();
}
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
consume();
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
static class Producer implements Runnable {
List<Integer> goods;
public Producer(List<Integer> goods) {
this.goods = goods;
}
public void produce(int i) {
synchronized (goods) {
if (goods.size() >= maxSize) {
try {
goods.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ">>> producing >> " + i);
goods.add(i);
goods.notifyAll();
}
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
produce(i);
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
List<Integer> goods = new ArrayList<>();
Consumer consumer = new Consumer(goods);
Producer producer = new Producer(goods);
Thread consumerWorker1 = new Thread(consumer);
Thread consumerWorker2 = new Thread(consumer);
Thread prroducerWorker1 = new Thread(producer);
Thread prroducerWorker2 = new Thread(producer);
consumerWorker1.start();
consumerWorker2.start();
prroducerWorker1.start();
prroducerWorker2.start();
try {
consumerWorker1.join();
consumerWorker2.join();
prroducerWorker1.join();
prroducerWorker2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Job completed >>>>");
}
}
程序的输出
线程 2>>> 产生 >> 0
Thread-1 >>> 消费 >>>0
线程 3>>> 产生 >> 0
线程“Thread-0”java.lang.IndexOutOfBoundsException 中的异常: 索引:0,大小:0 在 java.util.ArrayList.rangeCheck(ArrayList.java:657) 在 java.util.ArrayList.remove(ArrayList.java:496) 在 com.threading.TestConsumerProducer2$Consumer.consume(TestConsumerProducer2.java:27) 在 com.threading.TestConsumerProducer2$Consumer.run(TestConsumerProducer2.java:35) 在 java.lang.Thread.run(Thread.java:748) Thread-2>>> 产生 >> 1
Thread-1 >>> 消费 >>>0
线程 3>>> 产生 >> 1
线程 1 >>> 消耗 >>>1
线程 2>>> 产生 >> 2
线程 1 >>> 消耗 >>>1
线程 3>>> 产生 >> 2
线程 1 >>> 消耗 >>>2
线程 2>>> 产生 >> 3
线程 1 >>> 消耗 >>>2
线程 2>>> 产生 >> 4
线程 3>>> 产生 >> 3
线程 1 >>> 消耗 >>>3
线程 2>>> 产生 >> 5
线程 1 >>> 消耗 >>>4
线程 3>>> 产生 >> 4
Thread-1 >>> 消费 >>>3
Thread-2>>> 生产 >> 6 Thread-1 >>>> 消费 >>>5
线程 2>>> 产生 >> 7
线程 3>>> 产生 >> 5
问题陈述: 为什么没有一个线程执行 10 次? 代码中的死锁情况在哪里? 当 Goods 对象被消费者线程锁定并且如果 size
【问题讨论】:
-
您标记的前面是生产者-消费者问题中的一种基本问题。在这里,我试图使用更多的线程来实现相同的逻辑,但更复杂。所以在上一个问题中分配了两个线程来执行这两个操作,所以每个线程对每个操作都进行了分配,但是在这里为每个操作分配了两个线程。
标签: java multithreading producer-consumer