手写生产者—消费者模式

生产者—消费者模式是一个很好的并发的问题

先说几个基础的点:

  1. wait(), notify(), notifyAll()都是Object的函数
  2. notify()仅仅通知一个线程,并且不知道通知哪一个线程,而notifyAll()会通知所有等待中的线程
  3. 在多线程共享的那个Object中使用wait(),在生产者消费者问题中,这个共享的Object就是共享缓冲区
  4. 在多线程共享的那个Object应该被synchronized,在生产者消费者问题中,这个共享的Object就是共享缓冲区
  5. 永远在循环里调用wait()而不是if语句中

实现生产者-消费者模式有几点:

  1. 用什么作为缓冲区,给生产者和消费者解耦,一般使用队列
  2. 构建生产者,队列满生产者线程阻塞
  3. 构建消费者,队列空消费者线程阻塞

带着这个思路去手写一个生产者-消费者模式:

一个箱子,也就是共享缓冲区:

public class Box {
	Queue<Integer> queue = new LinkedList<>();
	int maxSize = 50;
	
	/** 放入 */
	public void put(int product) {
		synchronized(this) {
			while(queue.size() >= maxSize) {
				try {
					System.out.println("队列满了,生产者等待");
					wait();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			queue.add(product);
                        System.out.println("放入一个商品,现在有" + queue.size() + "个商品");
			notifyAll();
			
		}
	}
	
	/** 取出 */
	public void take() {
		synchronized(this) {
			while(queue.size() <= 0) {
				try {
					System.out.println("队列空了,消费者等待");
					wait();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			queue.remove();
                        System.out.println("取出一个商品,现在有" + queue.size() + "个商品");
			notifyAll();
			
		}
	}
}

生产者:

public class Producer extends Thread {

	Box box;

	public Producer(Box box) {
		this.box = box;
	}

	@Override
	public void run() {
		while(true) {
			try {
				int i = new Random().nextInt(100);
				box.put(i);
                                // 随机休眠
				Thread.sleep(new Random().nextInt(1000));
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}
	
}

消费者:

public class Consumer extends Thread {
	
	Box box;

	public Consumer(Box box) {
		this.box = box;
	}
	
	@Override
	public void run() {
		while(true) {
			try {
				box.take();
                                // 随机休眠
				Thread.sleep(new Random().nextInt(1000));
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}
	
}

测试:

public class Test {
	
	public static void main(String[] args) {
		
		Box box = new Box();
		// 随便来几个生产者几个消费者
		for (int i = 0; i < 8; i++) {
			new Producer(box).start();
			
		}
		for (int i = 0; i < 4; i++) {
			new Consumer(box).start();
		}
		
	}
}

截取最后部分运行结果:

取出一个商品,现在有42个商品
放入一个商品,现在有43个商品
放入一个商品,现在有44个商品
放入一个商品,现在有45个商品
放入一个商品,现在有46个商品
放入一个商品,现在有47个商品
放入一个商品,现在有48个商品
取出一个商品,现在有47个商品
放入一个商品,现在有48个商品
放入一个商品,现在有49个商品
放入一个商品,现在有50个商品
队列满了,生产者等待
队列满了,生产者等待
队列满了,生产者等待
队列满了,生产者等待
取出一个商品,现在有49个商品
放入一个商品,现在有50个商品
队列满了,生产者等待
队列满了,生产者等待
队列满了,生产者等待
取出一个商品,现在有49个商品
放入一个商品,现在有50个商品
队列满了,生产者等待
队列满了,生产者等待
队列满了,生产者等待
取出一个商品,现在有49个商品
放入一个商品,现在有50个商品
队列满了,生产者等待
队列满了,生产者等待
队列满了,生产者等待
队列满了,生产者等待
取出一个商品,现在有49个商品
放入一个商品,现在有50个商品
队列满了,生产者等待
队列满了,生产者等待
队列满了,生产者等待
取出一个商品,现在有49个商品
放入一个商品,现在有50个商品

最后

这个是比较基础的一个生产者消费者模式,除了使用wait(), notifyAll()这种方式来实现,还可以通过阻塞队列来实现。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值