java多线程之生产者与消费者

生产者与消费者问题

  • 经典生产者与消费者问题
  • 生产者不断的往仓库中存放产品,消费者从仓库中消费产品。
  • 其中生产者和消费者都可以有若干个。
  • 仓库规则:容量有限,库满时不能存放,库空时不能取产品 。
    /*
    首先定义产品类:
    产品类可简单可复杂这里我就以简单的产品id和产品名字来定义产品类
    package product;
    /**
  • 产品类
    */
    class Product {
private int id;// 产品id
	private String name;// 产品名称
public Product(int id, String name) {
	this.id = id;
	this.name = name;
}
public String toString() {
		return "(产品ID:" + id + " 产品名称:" + name + ")";
	}
public int getId() {
	return id;
}
public void setId(int id) {
	this.id = id;
}
public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}

}
以上就是产品类的相关内容
接下来是生产者(这里我使用的类都是继承了Runnable方法)
/**

  • 生产者
    */
    class Producer implements Runnable {
    private Storage storage;//这个是仓库类(在下文实现)
    public Producer(Storage storage) {
    this.storage = storage;
    }
    @Override
    public void run() {
    int i = 0;
    Random r = new Random();
    while(i<10)//为什么这里是10,因为我定义的仓库大小就是10,详见下文
    {
    i++;
    Product product = new Product(i, “电话” + r.nextInt(100));
    storage.push(product);//这里的方法统统都在下面
    }
    }
    }

这是消费者:

/**## 标题

  • 消费者
    */
    class Consumer implements Runnable {
    private Storage storage;
    public Consumer(Storage storage) {
    this.storage = storage;
    }

    public void run() {
    int i = 0;
    while(i<10)
    {
    i++;
    storage.pop();
    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    }
    }
    到了重头戏的仓库类了,下面的内容有一些小小的难度,不过我相信看到这篇博客的大佬,一定难不住你,一起来看看吧
    首先我们要先知道仓库的主要功能,首先仓库功能要有存储产品功能(在这里我把消费功能写到了仓库中,等下会着重告诉)
    代码如下:
    /**
    *仓库
    */
    class Storage {
    // 仓库容量为10
    private Product[] products = new Product[10];
    private int top = 0;
    // 生产者往仓库中放入产品
    public synchronized void push(Product product)//这个方法执行一次就会生产一个商品
    //这里说一下sychronized是线程锁关键字
    简单来说就是只有一个线程能执行,在执行时其他线程必须等待,不得干扰
    {
    while (top == products.length) {
    try {
    System.out.println(“producer wait”);
    wait();//仓库已满,等待
    } catch (InterruptedException e) {
    }
    }
    //把产品放入仓库
    products[top++] = product;
    System.out.println(Thread.currentThread().getName() + " 生产了产品"
    + product);
    System.out.println(“producer notifyAll”);
    notifyAll();//唤醒等待线程
    }
    接下来是消费的方法:
    // 消费者从仓库中取出产品
    public synchronized Product pop() {
    while (top == 0) {
    try {
    System.out.println(“consumer wait”);
    wait();//仓库空,等待
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    //从仓库中取产品
    –top;
    Product p = new Product(products[top].getId(), products[top].getName());
    products[top] = null;
    System.out.println(Thread.currentThread().getName() + " 消费了产品" + p);
    System.out.println(“comsumer notifyAll”);
    notifyAll();//唤醒等待线程
    return p;
    }
    }
    至此我们的生产者消费者的四个类(生产者,消费者,商品,仓库)就已经完成了
    接下来就让我们编写一个测试类:
    public class ProductTest {
    public static void main(String[] args) throws InterruptedException {
    Storage storage = new Storage();

     Thread consumer1 = new Thread(new Consumer(storage));
     consumer1.setName("消费者1");
     Thread consumer2 = new Thread(new Consumer(storage));
     consumer2.setName("消费者2");
     Thread producer1 = new Thread(new Producer(storage));
     producer1.setName("生产者1");
     Thread producer2 = new Thread(new Producer(storage));
     producer2.setName("生产者2");
     
     producer1.start();
     producer2.start();
     Thread.sleep(1000);		
     consumer1.start();
     consumer2.start();		
     //注意在这里呢你可能执行之后看到结果会很懵,我就来给你解释一下: 首先呢我先让生产者来执行(我已经提前规定好了仓库的大小只能为10)所以生产者的两个线程在生产了10个商品 之后就会退出执行,然后休眠1秒钟之后消费者就会参与其中执行)
    

    }

发布了4 篇原创文章 · 获赞 7 · 访问量 2468

猜你喜欢

转载自blog.csdn.net/weixin_43536818/article/details/104159270