美文网首页程序员
生产者与消费者

生产者与消费者

作者: 树獭非懒 | 来源:发表于2018-06-09 16:16 被阅读28次

我们来实现这样一个效果

放入20个苹果和取出20个苹果。生产者每次向篮子里放五个苹果,消费者依次取出篮子里的苹果。取出五个苹果后,生产者才能继续往篮子里放。

一、先创建生产者和消费者

1.创建生产者

新建一个生产者继承Thread,目的是向篮子里面放苹果(run方法里面实现)

class Productor extends Thread

{

private Basket basket=null;

public Productor(Basket basket)

{

super();

this.basket=basket;

}

public void run()

{

basket.pushApple();//向篮子里面放苹果

}

}

2.创建消费者

新建一个消费者继承Thread,目的是从篮子里取苹果

class Consumer extends Thread

{

private Basket basket=null;

public Consumer(Basket basket)

{

super();

this.basket=basket;

}

public void run()

{

basket.popApple();//从篮子里面取苹果

}

}

二、实现放苹果和取苹果方法

1.创建篮子类和苹果类

放苹果和取苹果都需要操作篮子和苹果这两个对象,所以我们先创建篮子和苹果类

苹果类很简单,就是一个简单的javaBean。包含苹果的id属性。

class Apple{

private int id;

Apple(int id)

{

this.id=id;

}

public String toString()

{

return "苹果"+id;

}

}

篮子类稍微有点复杂,主要目的就是实现放苹果和取苹果的逻辑

先用一个集合(这里用的是链表集合)存放苹果,用链表集合有个好处,既可以实现先放入的先拿出来,又可以实现先放入的后拿出来。

然后用两个循环分别实现放入20个苹果和取出20个苹果。

class Basket{

private LinkedList basket=new LinkedList();

public synchronized void pushApple()

{

for(int i=1;i<=20;i++)

{

Apple apple=new Apple(i);

push(apple);

}

}

public synchronized void popApple()

{

for(int i=1;i<=20;i++)

{

pop();

}

}

public void push(Apple apple)

{

...

}

private void pop()

{

...

}

}

2.实现生产者放苹果和消费者取苹果

在(1)中可以看到,放苹果pushApple()方法和取苹果popApple中加入了synchronized,实现了这两者的同步方法。即放的时候不能取,取的时候不能放。

接下来看放苹果和取苹果的逻辑

如果篮子里的苹果数不为5.那么就每隔500ms放入一个苹果。即将苹果对象加入到篮子集合中。

当放入5个苹果后,让这个生产者开始等待并唤醒消费者。

此时消费者出场了,消费者开始消费苹果,每隔500ms取出一个。当全部取出时,消费者开始等待并唤醒生产者。

这样一直循环下去,直到放20个苹果和取20个苹果完成后,结束任务。

public void push(Apple apple)

{

if(basket.size()==5)

{

try{

wait();

}catch(InterruptedException e)

{

    System.out.println("放入苹果异常"+Thread.currentThread().isInterrupted());

}

}

try{

Thread.sleep(500);

}catch(InterruptedException e)

{

System.out.println("放入苹果异常"+Thread.currentThread().isInterrupted());

}

basket.addFirst(apple);

System.out.println("存放"+apple.toString());

notifyAll();

}

private void pop()

{

if(basket.size()==0)

{

try{

wait();

}catch(InterruptedException e)

{

e.printStackTrace();

}

}

try{

Thread.sleep(500);

}catch(InterruptedException e)

{

e.printStackTrace();

}

Apple apple=basket.removeFirst();

System.out.println("吃掉"+apple.toString());

notifyAll();

}

三、测试

创建生产者和消费者对象,并开始生产和消费

public class ProductConsumerDemo

{

public static void main(String[] args){

Basket basket=new Basket();

Productor productor=new Productor(basket);

Consumer consumer=new Consumer(basket);

productor.start(); consumer.start();

}

}

可以看到下面的运行结果:

四、知识拓展

上面代码中在实现wait()方法中会捕捉InterruptedException异常,那么什么情况下会抛出这个异常呢?

这个异常是中断异常,调用线程的interrupt()方法就会抛出这个异常。

比如下面

Thread.sleep(10000);

productor.interrupt();

这样就可以实现10秒后让product也就是生产者抛出中断异常。

相关文章

  • kafka理解

    kafka生产者、消费者与分区的分配关系 生产者如何传输到分区消费者如何从分区读取生产者、消费者与分区的关系 主题...

  • Java 并发编程——生产者与消费者

    1. 生产者与消费者 1.1 程序基本实现(问题引出) 生产者与消费者是线程操作的经典案例,即:生产者不断生产,消...

  • java多线程

    生产者与消费者问题

  • Node下的RabbitMQ应用

    一个最简单的生产者与消费者建立过程 创建生产者 创建消费者

  • 操作系统知识点持续更新

    生产者消费者问题 关于生产者消费者问题可以参考这篇文章:生产者消费者问题的java实现 临界区与互斥量 临界区:保...

  • 生产者与消费者模型

    生产者与消费者模型 通过使用Object的wait(),notify()方法进行生产者与消费者模型中出现的数据同步...

  • 2-1.死锁-经典同步问题

    三、经典同步问题 1.生产者-消费者问题 计算机系统中的许多问题都可归结为生产者与消费者问题,生产者与消费者可以通...

  • 生产者与消费者模式

    一、模式特点 生产者与消费者模式中,生产者和消费者各自做着自己的工作,生产者生产物品,将物品放入缓冲区。消费者从缓...

  • 生产者-消费者 模型

    生产者与消费者基本程序模型 在多线程开发过程之中最为著名的案例就是生产者与消费者操作,该操作的主要流程如下:生产者...

  • 生产者与消费者

    使用BlockingQueue模拟生产者与消费者

网友评论

    本文标题:生产者与消费者

    本文链接:https://www.haomeiwen.com/subject/fnwteftx.html