题目:一条线程模拟生产者,另一条线程模拟消费者。生产者生产一次商品,消费者就消费一次商品。生产和消费的数量使用随机数表示,要求每次生产的产品数量加上上一次剩余的数量不能超过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();// 消费者消费
}
}
某一次,某一时刻程序运行结果。