`
wang吖
  • 浏览: 240716 次
  • 性别: 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多线程的核心概念、实现方式以及相关工具的使用。 一、多线程基础 1. 线程与进程:在操作系统中,进程是资源分配的基本单位,而线程是程序执行的基本单位。每个进程至少有一个主线程,...

    java多线程笔记

    生产者消费者模型是常见的多线程协作模式,通过`BlockingQueue`等工具实现线程间的通信和同步。死锁是指两个或更多线程相互等待对方释放资源而无法继续执行的情况,应避免创建这样的循环等待。线程之间的数据传递...

    Java多线程详解(超详细)_狂神说笔记完整版_项目代码_适合小白随课程学习

    - 生产者-消费者问题:一个线程生产数据,另一个线程消费数据,需要避免生产者过度生产或消费者提前消费。 - 死锁:两个或更多线程互相等待对方释放资源,导致所有线程都无法继续执行。 - 管道(Pipe)和缓冲区...

    Java多线程文章系列.pdf

    #### 五、Java多线程学习笔记 ##### 1. 线程类 - **Thread类**: - 提供了创建和控制线程的方法。 - 可以通过继承`Thread`类或实现`Runnable`接口来创建线程。 ##### 2. 等待一个线程的结束 - **join()方法**: -...

    JUC学习笔记(Java多线程)

    还有`BlockingQueue`,它是生产者-消费者模型的基础,如`ArrayBlockingQueue`、`LinkedBlockingQueue`等,它们在满时阻塞生产者,在空时阻塞消费者,确保了数据的一致性。 JUC还引入了`Semaphore`信号量,用于限制...

    java多线程学习笔记

    - **BlockingQueue**:队列接口,常用于生产者消费者模型,如ArrayBlockingQueue、LinkedBlockingQueue等。 - **CountDownLatch/CyclicBarrier/Semaphore**:高级并发工具类,用于协调多线程之间的协作。 5. **...

    2022年Java学习笔记-Java课程配套案例.rar

    也可能包含多线程的实战,比如生产者消费者模型等。这些案例旨在帮助学习者通过实践加深理解,提高编程能力。建议按照案例的指导逐步学习,遇到问题时查阅相关文档或在线资源,以期全面掌握Java编程。

    Java并发实践-学习笔记

    在Java编程领域,多线程和并发处理是不可或缺的一部分,特别是在设计高性能、高...通过深入学习这份"Java并发实践-学习笔记",开发者能够提升自己在处理多线程和并发问题上的能力,从而设计出更高效、更稳定的应用。

    JAVA并发编程实践-构建执行程序块-学习笔记

    阻塞队列和⽣产者-消费者模式是指在多线程环境下,使用阻塞队列来实现生产者-消费者模式。例如,在桌⾯搜索时,使用阻塞队列来实现生产者-消费者模式,以确保线程安全。 实例1 桌⾯搜索是指在桌⾯搜索时,使用多...

    Java线程编程学习笔记(二)

    这篇“Java线程编程学习笔记(二)”很可能是对Java并发编程深入探讨的一部分,特别是涉及多线程示例的实践应用。我们将从标题、描述以及标签来推测可能涵盖的知识点,并结合"Multi-Threads Demo"这一压缩包文件名来...

    java实战经典学习笔记

    - 生产者消费者模型。 - 线程安全问题。 #### 十、泛型 - **泛型的基本概念** - 泛型的定义。 - 为什么使用泛型。 - **泛型的使用** - 泛型类和泛型方法。 - 通配符的使用。 - **泛型操作范例** - 泛型在...

    Java笔记---李兴华

    6. **支持多线程**:Java内置了对多线程的支持,可以轻松地编写并发执行的程序。 #### 四、Java与编译型语言 Java虽然通常被视为解释型语言,但实际上它结合了编译和解释两种方式。Java源代码先被编译成字节码,...

    马士兵多线程训练营笔记

    5. **线程通信**:wait()、notify()、notifyAll()方法的使用,以及在生产者消费者模型、哲学家就餐问题等经典示例中的应用。 6. **线程池**:ExecutorService、ThreadPoolExecutor和Future接口的理解,线程池的配置...

    多线程学习笔记.docx

    这种模式通常借助于BlockingQueue(阻塞队列)来实现,生产者将数据放入队列,消费者从队列中取出数据,队列满时生产者会阻塞,队列空时消费者会阻塞。 在Java中,线程有六种状态:NEW、RUNNABLE、BLOCKED、WAITING...

    JAVA经典教材笔记

    - 生产者-消费者模型:使用阻塞队列实现。 - 生产者-消费者模型的优点:解耦生产者与消费者。 - **线程生命周期** - 线程的状态:NEW、RUNNABLE、BLOCKED等。 - 线程状态转换图。 #### 第十章:泛型 - **泛型...

    Java并发编程学习笔记.rar

    9. **并发模式**:包括生产者消费者模型、读写者模型、工作窃取等,这些模式有助于优化并发程序的性能。 10. **JVM内存模型**:理解Java内存模型(JMM)对于理解并发编程中的可见性和一致性至关重要。JMM规定了线程...

    达内内网学习笔记 Java SE核心

    - 线程通信:生产者消费者模型、线程池。 8. **反射机制**: - Class类:获取类信息,创建对象,调用方法。 - 构造器的反射调用:newInstance()方法。 - 方法和字段的反射操作:getMethod()、getField()等。 9...

    个人学习-JUC-笔记

    - **BlockingQueue**:阻塞队列,常用于生产者-消费者模型,如ArrayBlockingQueue、LinkedBlockingQueue。 6. **原子类** - **Atomic包**:如AtomicInteger、AtomicLong等,提供原子操作,避免显式锁定。 7. **...

    cccctyl-java-basic-notes-master_java_

    【标题】"cccctyl-java-basic-notes-master_java_" 指的可能是一个关于Java基础学习的项目,其中包含了作者cccctyl对Java编程语言核心概念的深入理解和实践笔记。这个项目特别关注了权限设置和安全模块,这在任何...

    线程学习实例和笔记

    Java并发编程中常见的模型有生产者消费者模型、读者写者模型、哲学家就餐问题等。这些模型为解决特定的并发问题提供了理论基础。 五、源码分析 了解线程的工作原理,查看JVM和Java库的源码是非常有益的。例如,可以...

Global site tag (gtag.js) - Google Analytics