我试图为消费者创建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 >>>>");
}
}
输出程序
Thread-2 >>>生产>> 0
线程-1 >>>>消耗>>> 0
Thread-3 >>>制作>> 0
线程“Thread-0”中的异常java.lang.IndexOutOfBoundsException:索引:0,大小:0,位于java.util.ArrayList.remove(ArrayList.java:496)的java.util.ArrayList.rangeCheck(ArrayList.java:657) )com.threading.TestConsumerProducer2 $ Consumer.consume(TestConsumerProducer2.java:27)at com.threading.TestConsumerProducer2 $ Consumer.run(TestConsumerProducer2.java:35)at java.lang.Thread.run(Thread.java:748) Thread-2 >>>制作>> 1
线程-1 >>>>消耗>>> 0
Thread-3 >>>制作>> 1
线程-1 >>>>消耗>>> 1
Thread-2 >>>制作>> 2
线程-1 >>>>消耗>>> 1
Thread-3 >>>制作>> 2
线程-1 >>>>消耗>>> 2
Thread-2 >>>制作>> 3
线程-1 >>>>消耗>>> 2
Thread-2 >>>生产>> 4
Thread-3 >>>制作>> 3
线程-1 >>>>消费>>> 3
Thread-2 >>>生产>> 5
线程-1 >>>>消费>>> 4
Thread-3 >>>制作>> 4
线程-1 >>>>消费>>> 3
Thread-2 >>>制作>> 6 Thread-1 >>>>消费>>> 5
Thread-2 >>>生产>> 7
Thread-3 >>>制作>> 5
问题陈述:为什么没有一个线程执行10次?代码中的死锁情况在哪里?当Goods对象被消费者线程锁定并且size <= 0时,为什么会出现IndexOutOfBoundsException它应该进入等待状态?