生产—消费类问题
仓库类(例如Storage):
资源池(例list):存放产品
生产方法(例pro):向资源池中添加产品
消费方法(例con):消耗资源池中的产品
生产者类(例Producer):
调用仓库类中的生产方法 ( 例getPro() )
消费者类(Consumer):
调用仓库类中的消费方法 ( 例getCon() )
测试类:
生产者类——线程
消费者类——线程
条件:
要生产num个数量,如果仓库没有足够的空间,则暂停生产;再次满足条件时,应唤醒线程;
要消费num个数量,如果仓库库存不足,则暂停消费。再次满足时,应唤醒线程;
举栗子
import java.util.ArrayList;
import java.util.List;
public class Demo4 {
public static void main(String[] args) {
Storage storage=new Storage();
Producer pro1=new Producer(storage,70);
Producer pro2=new Producer(storage,150);
Producer pro3=new Producer(storage,100);
Producer pro4=new Producer(storage,40);
pro1.start();
pro2.start();
pro3.start();
pro4.start();
Consumer cons1=new Consumer(storage);
Consumer cons2=new Consumer(storage);
Consumer cons3=new Consumer(storage);
Consumer cons4=new Consumer(storage);
cons1.setNum(120);
cons2.setNum(80);
cons3.setNum(40);
cons4.setNum(100);
cons1.start();
cons2.start();
cons3.start();
cons4.start();
}
}
//仓库类
class Storage{
private List<Object> list=new ArrayList<Object>();//资源池
private final static int MAX_SIZE=200;//资源池大小
//生产方法
/*
* 生产方法
* num:生产产品数量
*/
public synchronized void pro(int num){//A-挂起;B-满足条件,唤醒所有持有相同同步锁的线程
//仓库存放空间
//200库存--150空间
//pro(160)--阻塞/被唤醒
//pro(60)--可以生产,唤醒,生产 --90空间
while(num>Storage.MAX_SIZE-list.size()){
//不能生产,等价于将线程挂起
try {
System.out.println("【要生产:"+num+"个产品,目前库存:"+list.size()+",暂时不能生产】");
this.wait();//将当前持同一同步锁的线程阻塞等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();//唤醒所有持有相同同步锁的线程
//生产
for(int i=1;i<=num;i++){
list.add(new Object());
}
System.out.println("共生产了:"+num+"个商口,目前库存是:"+list.size());
}
//消费方法
public void cons(int num){
synchronized(this){
//不能消费
while(num>list.size()){
try {
System.out.println("【消费:"+num+"个产品,目前库存是:"+list.size()+",暂时不满足消费条件】");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
for(int i=0;i<num;i++){
list.remove(0);
}
System.out.println("已消费:"+num+"个产品,库存是:"+list.size());
}
}
}
//生产者类
class Producer extends Thread{
private Storage storage;
private int num;
public Producer(Storage storage,int num) {
this.storage=storage;
this.num=num;
}
@Override
public void run() {
storage.pro(num);
}
}
//消费者类
class Consumer extends Thread{
private Storage storage
;
private int num;//消费者消费数量
public void setNum(int num){
this.num=num;
}
public Consumer(Storage storage) {
this.storage=storage;
}
@Override
public void run() {
storage.cons(num);
}
}
其中:synchronized:定义同步代码
同步代码块:
synchronized(同步锁){
//同步的代码块
}
同步锁:
类锁:
类.class
对象锁:
方式一:创建的对象的同一个,例:static
方式二:在构造器中传入一个对象类型的参数
例:class T implements Runnable{
String ss;
T(String ss){
this.ss=ss;
}
}
wait:让出所持有的同步锁
notify / notifyAll:唤醒持有相同同步锁的对象