`
wang吖
  • 浏览: 234257 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java多线程-传统线程实现生产者消费者模型-学习笔记

 
阅读更多

Java中的生产者消费者模型属于编程中的经典模型,下面利用线程简单模拟一下这个模型,例子:两个生产者生产馍馍(馒头),往装馍馍的篮子里面放,篮子用数组模拟栈先进后出且大小为10,当生产者把篮子装满了即等着同时通知消费者消费;当消费者把篮子消费空了即刻等着同时通知生产者生产。

代码并不复杂,使用线程同步关键字synchronized即可完成……

 

Coding:

/**
 * 利用传统线程实现生产者消费者模型
 * 
 * 利用两根线程生产20个馍馍,一根线程消费20个馍馍,协调作业,
 * 
 * <li>一根线程 wait 则需要调用 notify 方法 </li>
 * <li>多根线程 wait 则需要调用 notifyAll 方法</li>
 * 
 * 注意:
 * <li>wait 方法在等待的同时会释放对象锁,让其它的线程有机会获取对象锁</li>
 * <li>sleep 方法在休眠的时候不会释放对象锁,其它的线程无法获取对象锁</li>
 * 
 * @author 吖大哥
 * @date Jun 2, 2014 2:13:01 PM
 */
public class ProducerConsumer {

	public static void main(String[] args) {
		BasketStack bs = new BasketStack();
		Producer p = new Producer(bs);
		Consumer c = new Consumer(bs);
		// 生产者生产20个馍馍
		new Thread(p).start();
		new Thread(p).start();
		// 消费者消费20个馍馍
		new Thread(c).start();
	}
}

// 馍馍(馒头)
class MoMo {

	private int id;// 馍馍编号

	public MoMo(int id) {
		this.id = id;
	}

	@Override
	public String toString() {
		return "===momo id===" + id;
	}
}

// 装馍馍的篮子
class BasketStack {

	private int index;
	// 可以装馍馍的数组
	private MoMo[] momoArr = new MoMo[10];

	// 向篮子里面放馍馍
	public synchronized void push(MoMo momo) {
		// if (index == momoArr.length) {
		// 利用while可以起到双重保险,如果this.wait()出现异常被打断,循环依然可以进行一次判断保证程序不往下执行
		while (index == momoArr.length) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		momoArr[index] = momo;
		index++;
		this.notifyAll();// 通知消费者来消费
	}

	// 从篮子里面取馍馍
	public synchronized MoMo pop() {
		// if (index == 0) {
		// 利用while可以起到双重保险,如果this.wait()出现异常被打断,循环依然可以进行一次判断保证程序不往下执行
		while (index == 0) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notifyAll();// 通知生产者来生产
		index--;
		return momoArr[index];
	}
}

// 生产者线程
class Producer implements Runnable {

	private BasketStack bs = new BasketStack();// 装馍馍的篮子

	public Producer(BasketStack bs) {
		this.bs = bs;
	}

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			MoMo moMo = new MoMo(i);
			System.out.println("生产了 " + moMo);
			bs.push(moMo);
			try {
				Thread.sleep((int) (Math.random() * 1000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class Consumer implements Runnable {

	private BasketStack bs = new BasketStack();// 取馍馍的篮子

	public Consumer(BasketStack bs) {
		this.bs = bs;
	}

	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			MoMo moMo = bs.pop();
			System.out.println("消费了 " + moMo);
			try {
				Thread.sleep((int) (Math.random() * 1000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

 

 

分享到:
评论

相关推荐

    java多线程笔记

    Java线程:概念与原理 2 一、操作系统中线程和进程的概念 2 二、Java中的线程 3 三、Java中关于线程的名词解释...Java线程:并发协作-生产者消费者模型 52 Java线程:并发协作-死锁 55 Java线程:线程之间的数据传递 58

    bcb 多线程示例 MutilThread(生产者与消费者)

    bcb_多线程示例,学习笔记 MutilThread(生产者与消费者) 线程协调工作示例

    多线程学习笔记.docx

    包括线程和进程的关系,线程的三种创建方式,继承thread,实现runnable接口,实现callable接口,线程同步,生产者消费者模式

    Java并发编程(学习笔记).xmind

    生产者-消费者模式 中断的处理策略 传递InterruptedException 恢复中断,让更高层的代码处理 PriorityQueue(非并发) ConcurrentSkipListMap 替代同步的SortedMap ...

    Java开发详解.zip

    030905_【第9章:多线程】_线程操作案例——生产者和消费者笔记.pdf 030906_【第9章:多线程】_线程生命周期笔记.pdf 031001_【第10章:泛型】_泛型入门笔记.pdf 031002_【第10章:泛型】_通配符笔记.pdf 031003_...

    Caffe学习笔记-粗糙版

    从头至尾阅读了Caffe全部源码,过程中写了这个笔记,写的比较粗糙,但是包含了Caffe中所有重要部分源码的解析(除python接口、具体Layer层和tools),包括多线程训练部分和datalayer的lmdb数据读取(生产者消费者)...

    Java聊天室的设计与实现设计开题报告.doc

    " " "本题目为基于socket的网络编程,具体需要实现C/S模式的聊天程序,使用了java " " "语言,java语言有下面一些特点:简单、面向对象、分布式、解释执行、安全、体" " "系结构中立、可移植、高性能、多线程以及...

    Guava-Event-Bus:Guava的EventBus源码学习

    通过EventBus可以简化生产者/消费者 这种模型,同时又可以通过Executor来控制线程,使用起来非常优雅灵活。异步的则使用AsyncEventBus,如果需要强制使EventBus同步执行则可以使用@AllowConcurrentE

    学习笔记(01):19年并发编程及原理视频培训教程入门到精通-什么是并发编程

    立即学习:https://edu.csdn.net/course/play/9827/208778?utm_source=blogtoedu java并发编程。 串行和并行的区别:串行实质上是一个进程有一个线程。...任务本身需要协作执行:比如生产者消费者问题

    计算机操作系统(第三版)

    2.4.1 生产者—消费者问题 58 2.4.2 哲学家进餐问题 61 2.4.3 读者—写者问题 63 2.5 进程通信 65 2.5.1 进程通信的类型 65 2.5.2 消息传递通信的实现方法 66 2.5.3 消息传递系统实现中的若干问题 68 ...

Global site tag (gtag.js) - Google Analytics