资源描述类:
/**
* 资源描述类
* @author gaojh
*
*/
public class Product {
List<String> product = null;
public Product() {
super();
this.product = new ArrayList<>();
}
/**
* 生产方法
* @author: gaojh
* @throws InterruptedException
* @date: 2018年4月16日 下午3:53:29
*/
public synchronized void produce() throws InterruptedException{
if(product != null && product.size() < 1000){ //仅在产品List不为null且长度小于10时进行生产
String singleProduct = Thread.currentThread().getName() + "的产品";
product.add(singleProduct);
System.out.println(Thread.currentThread().getName()+"生产了"+singleProduct);
}else{
System.out.println(Thread.currentThread().getName()+"开始唤醒了");
this.notifyAll();
System.out.println(Thread.currentThread().getName()+"进入wait了");
this.wait();
}
}
/**
* 消费方法
* @author: gaojh
* @throws InterruptedException
* @date: 2018年4月16日 下午3:53:29
*/
public synchronized void consume() throws InterruptedException{
if(product != null && product.size() > 0){ //仅在产品List不为null且长度大于0时进行消费
String singleProduct = product.remove(0); //消费第一个
System.out.println(Thread.currentThread().getName()+"消费了"+singleProduct);
}else{
System.out.println(Thread.currentThread().getName()+"开始唤醒了");
this.notifyAll();
System.out.println(Thread.currentThread().getName()+"进入wait了");
this.wait();
}
}
}
生产者:
/**
* 生产者类
* @author gaojh
*
*/
public class Producer implements Runnable{
Product product = null;
public Producer(Product product) {
super();
this.product = product;
}
@Override
public void run() {
//生产逻辑
try {
while(true){
product.produce();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
消费者:
/**
* 消费者类
* @author gaojh
*
*/
public class Consumer implements Runnable{
Product product = null;
public Consumer(Product product) {
super();
this.product = product;
}
@Override
public void run() {
//消费逻辑
try {
while(true){
product.consume();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Main方法类:
/**
* 测试多生产多消费
* @author gaojh
*
*/
public class TestThread {
public static void main(String[] args) {
Product product = new Product(); //创建唯一资源
//生产者
Producer producer = new Producer(product);
Thread producer1 = new Thread(producer); //生产者1
producer1.setName("生产者1");
Thread producer2 = new Thread(producer); //生产者2
producer2.setName("生产者2");
Thread producer3 = new Thread(producer); //生产者3
producer3.setName("生产者3");
producer1.start();
producer2.start();
producer3.start();
//消费者
Consumer consumer = new Consumer(product);
Thread consumer1 = new Thread(consumer); //消费者1
consumer1.setName("消费者1");
Thread consumer2 = new Thread(consumer); //消费者2
consumer2.setName("消费者2");
Thread consumer3 = new Thread(consumer); //消费者3
consumer3.setName("消费者3");
consumer1.start();
consumer2.start();
consumer3.start();
}
}
问:为什么在notifyAll之后让当前线程wait?
答:当前线程既然已经执行到notifyAll了,说明当前线程该做的及该类型线程该做的都已经完成了,如果下次竞争syn的锁,当前线程再次竞争持有(很有可能),只是进来唤醒了其他线程而已,没有必要,wait至少可以让当前线程释放锁,等待被唤醒。这样竞争线程从6个变为5个,无论是生产者还是消费者进入等待,对方线程只有syn锁的数字几率都会变大。
PS:现在在产品满了/空了后,无法指定唤醒消费者/生产者,只能全部唤起然后一个一个判断。效率上不行,要想办法修改。