1.主要使用notifyAll和wait完成线程之间的通信
2.使用注意事项notifyAll和wait必须在同步代码块中使用,也可以是同步方法并且notifyAll和wait必须使用同一个锁对象进行操作,wait不能用if判断必须用while循环判断 防止虚假唤醒
1.首先创建一个共享仓库,仓库里存储的是手机
import java.util.ArrayList;
import java.util.List;
public class Depository {
private List<Phone> phoneList = new ArrayList();
public List<Phone> getPhoneList() {
return phoneList;
}
public void setPhoneList(List<Phone> phoneList) {
this.phoneList = phoneList;
}
@Override
public String toString() {
return "PhoneDepository{" +
"phoneList=" + phoneList +
'}';
}
public class Phone{
private String name;
private float price;
public Phone(String name, float price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Phone{" +
"name='" + name + '\'' +
", price='" + price + '\'' +
'}';
}
}
}
2.创建一个生产者
package com.yujie.pool.producer;
import com.yujie.pool.utils.Sleep;
import java.util.List;
import java.util.Random;
public class Producer implements Runnable{
private Depository depository;
public Producer(Depository depository) {
if(depository == null){
throw new NullPointerException("仓库不能为空");
}
this.depository = depository;
}
@Override
public void run() {
List<Depository.Phone> phoneList = depository.getPhoneList();
while (true){
synchronized (depository) {
//这里不能用if防止虚假唤醒,如果有库存就等待
while (phoneList.size() != 0){
try {
depository.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Depository depository = new Depository();
phoneList.add(depository.new Phone("小米5",new Random().nextInt(1888)));
phoneList.add(depository.new Phone("苹果6",new Random().nextInt(1888)));
for (Depository.Phone phone : phoneList) {
System.out.println("生产手机:"+phone);
}
System.out.println("生产手机,目前生产数量:" + phoneList.size());
System.out.println("==============生产结束================");
this.depository.notifyAll();
}
}
}
}
3.创建一个消费者
package com.yujie.pool.producer;
import com.yujie.pool.utils.Sleep;
import java.util.List;
public class Consumer implements Runnable {
private Depository depository;
Consumer(Depository depository) {
if(depository == null){
throw new NullPointerException("仓库不能为空");
}
this.depository = depository;
}
@Override
public void run() {
List<Depository.Phone> phoneList = depository.getPhoneList();
while (true){
synchronized (depository) {
//这里不能用if防止虚假唤醒,如果没有库存就等待
while (phoneList.size() == 0){
try {
depository.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (Depository.Phone phone : phoneList) {
System.out.println("卖出:"+phone);
}
System.out.println("------------卖出结束------------");
this.depository.notifyAll();
phoneList.clear();
}
}
}
}
4.测试
public class TestProducer {
public static void main(String[] args) {
Depository depository = new Depository();
Producer producer = new Producer(depository);
Consumer consumer = new Consumer(depository);
new Thread(producer).start();
new Thread(consumer).start();
}
}
生产手机:Phone{name='小米5', price='774.0'}
生产手机:Phone{name='苹果6', price='1337.0'}
生产手机,目前生产数量:2
==============生产结束================
卖出:Phone{name='小米5', price='774.0'}
卖出:Phone{name='苹果6', price='1337.0'}
------------卖出结束------------
生产手机:Phone{name='小米5', price='1099.0'}
生产手机:Phone{name='苹果6', price='857.0'}
生产手机,目前生产数量:2
==============生产结束================
卖出:Phone{name='小米5', price='1099.0'}
卖出:Phone{name='苹果6', price='857.0'}
------------卖出结束------------
生产手机:Phone{name='小米5', price='515.0'}
生产手机:Phone{name='苹果6', price='255.0'}
生产手机,目前生产数量:2
==============生产结束================
卖出:Phone{name='小米5', price='515.0'}
卖出:Phone{name='苹果6', price='255.0'}
------------卖出结束------------