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秒钟之后消费者就会参与其中执行)
    

    }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多线程生产者消费者模式是一种常见的并发编程模式,用于解决生产者消费者之间的数据交互问题。在Java中,可以使用多线程和相关的同步机制来实现生产者消费者模式。 在这种模式中,生产者负责生成数据,并将数据放入共享的缓冲区中,而消费者则从缓冲区中取出数据进行处理。为了保证线程安全和避免竞态条件,需要使用锁或其他同步机制来控制对共享缓冲区的访问。 以下是一个简单的Java多线程生产者消费者的示例代码: ```java import java.util.LinkedList; class ProducerConsumer { private LinkedList<Integer> buffer = new LinkedList<>(); private int capacity = 10; public void produce() throws InterruptedException { int value = 0; while (true) { synchronized (this) { while (buffer.size() == capacity) { wait(); } System.out.println("Producer produced: " + value); buffer.add(value++); notify(); Thread.sleep(1000); } } } public void consume() throws InterruptedException { while (true) { synchronized (this) { while (buffer.isEmpty()) { wait(); } int value = buffer.removeFirst(); System.out.println("Consumer consumed: " + value); notify(); Thread.sleep(1000); } } } } public class Main { public static void main(String[] args) { ProducerConsumer pc = new ProducerConsumer(); Thread producerThread = new Thread(() -> { try { pc.produce(); } catch (InterruptedException e) { e.printStackTrace(); } }); Thread consumerThread = new Thread(() -> { try { pc.consume(); } catch (InterruptedException e) { e.printStackTrace(); } }); producerThread.start(); consumerThread.start(); } } ``` 上述代码中,ProducerConsumer维护了一个缓冲区buffer和一个容量capacity。生产者通过调用produce方法向缓冲区中添加数据,消费者通过调用consume方法从缓冲区中取出数据。在生产者消费者的方法中,使用synchronized关键字来保证同一时间只有一个线程能够访问共享资源,并使用wait和notify方法来实现线程间的通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值