您当前的位置: 首页 > 

梁云亮

暂无认证

  • 2浏览

    0关注

    1211博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

生产者消费者问题

梁云亮 发布时间:2019-11-20 07:56:59 ,浏览量:2

题目:一条线程模拟生产者,另一条线程模拟消费者。生产者生产一次商品,消费者就消费一次商品。生产和消费的数量使用随机数表示,要求每次生产的产品数量加上上一次剩余的数量不能超过1000。

为了解决问题,我们引入了缓冲区的概念:生产者将生产好的数据放入“缓冲区”,消费者从“缓冲区”拿要处理的数据。 在这里插入图片描述 使用缓冲区的好处:

  • 解耦了生产者和消费者:生产者不需要和消费者直接打交道。
  • 实现线程的并发协作:有了缓冲区以后,生产者线程只需要往缓冲区里面放置数据,而不需要管消费者消费的情况;消费者只需要从缓冲区拿数据处理即可,也不需要管生产者生产的情况。 这样,就从逻辑上实现了“生产者线程”和“消费者线程”的分离。
  • 解决忙闲不均,提高效率:生产者生产数据慢时,缓冲区仍有数据,不影响消费者消费;消费者处理数据慢时,生产者仍然可以继续往缓冲区里面放置数据 。

具体实现: 第一步:提供一个表示缓存池的类:

public class CachePool {
    private int count; //缓冲池中产品数量
    boolean flag = true; //是否需要消费:true生产,false消费

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}

第二步:提供生产者

public class Producer implements Runnable {
	private CachePool pool;

	public Producer(CachePool pool) {
		this.pool = pool;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (pool) {
				if (!pool.flag) {// 需要消费
					try {
						pool.wait(); //生产进程进入阻塞队列
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

				int count = new Random().nextInt(1000 - pool.getCount())+1;
				pool.setCount(count + pool.getCount());

				System.out.println("实际生产的数量:" + count + "  本次提供的数量:" + pool.getCount());

				pool.flag = false;// 切换flag值
				pool.notify();// 唤醒
			}

		}
	}
}

第三步:提供消费者

public class Consumer implements Runnable {
	private CachePool pool;

	public Consumer(CachePool pool) {
		this.pool = pool;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (pool) {
				if (pool.flag) {
					try {
						pool.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

				int count = new Random().nextInt(pool.getCount())+1;// 随机消耗
				pool.setCount(pool.getCount() - count); // 剩余数量

				System.out.println("消费的数量:" + count + "   剩余数量:" + pool.getCount());

				pool.flag = true;// 修改flag
				pool.notify();// 唤醒线程
			}
		}
	}
}

第四步:提供测试代码

public class DemoTest {
	public static void main(String[] args) {
		CachePool pool = new CachePool();
		new Thread(new Producer(pool)).start();// 生产者生产
		new Thread(new Consumer(pool)).start();// 消费者消费
	}
}

某一次,某一时刻程序运行结果。 在这里插入图片描述

关注
打赏
1665409997
查看更多评论
立即登录/注册

微信扫码登录

0.0482s