生产者与消费者:也称为有限缓冲的问题
(1) 生产者:主要作用是生成一定量的数据放到缓冲区中,然后重复此过程
(2) 消费者:生产者生成好一定量到缓冲区的同时,消费者也在缓冲区消耗这些数据。
(3) 步骤:
① 因为生产者和消费者都是共享一块区域,即仓库
② 仓库是有容量上限的,当数量达到上限后,生产者不允许继续生产产品,当前线程进入等待状态,等待其他线程唤醒
③ 当仓库没有产品时,消费者不允许继续消费,当前线程进入等待状态,等待其他线程唤醒
(4) 代码实现:
① 生产者跟消费者之间消费的是产品,定义一个产品类
Public class Product{
Int id;//定义产品的唯一ID
//定义构造方法初始化产品id
Public Product(int id){
This.id=id;
}
}
② 定义一个仓库用来存放产品
Public class Repertory{
//定义一个集合类用于存放产品,规定仓库最大容量为10
Public LinkedList store=new LinkedList();
Public LinkedList getStore(){
Return store;
}
Public void setStore(LinkedList store){
This.store=store;
}
/*生产者
*push()用于存放产品
*参数:第一个是产品对象
*第二是线程名称,用来显示是谁生产的
*使用synchronized关键字修饰方法
*最多只能一个有一个线程同时访问方法
*/
Public synchronized void push(Product p,String threadName){
/*仓库容量最大值为10,当容量=10时进入等待状态,等待其他线程*唤醒,唤醒后继续循环,等到仓库的存量小于10,跳出循环继续向*下执行准备生产产品
*/
While(store.size()==10){
Try{
//打印日志
System.out.println(threadName+”报告:仓库已满->进入等待状态->呼叫消费者消费”);
//仓库容量已满,进入等待状态,等待被唤醒
This.wait();
} catch(Exception e){
}
}
This.notifyAll();//唤醒所有等待线程
Store.addLast(p);//将产品添加到仓库中
System.out.println(threadName+”生产’+p.id+”号产品”+” ”+”当前库存:”+store.size());
Try{
Thread.sleep(1000);
}catch(Exception e){
}
}
/*消费者方法
*pop()方法用于存放产品
*/
Public synchronized void pop(String threadName){
//仓库没有存货,消费者进入等待被唤醒,唤醒后进行循环
While(store.size()==0){
Try{
System.out.println(threadName+”仓库已空,进入等待,生产者生成产品”);
This.wait();
} catch(Exception e){}
}
This.notifyAll();//唤醒所有等待线程
System.out.println(threadName+”消费了:”+store.removeFirst().id+”号产品”+” ”+”当前库存:”
Try{
Thread.sleep();
}catch(Exception e){
}
}
}
③ 定义生产者
Public class Producer implements Runnable{
//定义一个静态变量记录产品号数,唯一
Public static Integer count=0;
Repertory repertory=null;//定义仓库
Public Producer(Repertory repertory){
This.repertory=repertory;
}
@Override
Public void run(){
While(true){
Synchronized(Producer.class){
Count++;
Product product=new Product(count);
Repertory.push(product,thread.currentThread().getName());
}
}
}
}
④ 定义一个消费者
Public class Consumer implements Runnable{
Repertory repertory=null;//定义仓库
Public Consumer(Repertory repertory){
This.repertory=repertory;
}
@Override
Public void run(){
While(true){
Repertory.pop(Thread.currentThread().getName());
}
}
}
网友评论