`
woxiaoe
  • 浏览: 283518 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Java线程学习笔记(九)生产者消费者问题

    博客分类:
  • Java
阅读更多

用多线程来模拟生产者消费者问题。用到BlockingQueue来实现更方便和安全。

 

模拟一个厨师生成产品,消费者消费,当产品数大于10的时候厨师休息,但产品数不够时厨师接着工作。

 

 

package com.woxiaoe.study.thread;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 生产者 消费者 模拟
 * @author 小e
 *
 * 2010-4-29 下午09:32:43
 */

class Cook implements Runnable{
	private int productId;
	private BlockingQueue<Product> products;
	private boolean rest;
	public Cook(BlockingQueue<Product> products) {
		this.products = products;
	}
	public void product(){
		Product product = new Product(productId ++ );
		System.out.println("生产了" + product);
		products.add(product);
	}
	
	public boolean isRest() {
		return rest;
	}
	public void setRest(boolean rest){
		this.rest = rest;
	}
	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {
				synchronized (this) {
					while(products.size() >= 10){
						System.out.println("有剩余产品,厨师休息…………");
						rest = true;
						wait();
					}
				}
				product();// 50ms生产一个
				TimeUnit.MILLISECONDS.sleep(50);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("停止生产!");
		}
	}
}
class Product{
	private int productId;
	Product(int productId){
		this.productId = productId;
	}
	public int getProductId() {
		return productId;
	}
	
	@Override
	public String toString() {
		return "产品" + productId;
	}
}
class Customer implements Runnable{
	private BlockingQueue<Product> products;
	private String name;
	private Cook cook;
	public Customer(Cook cook,BlockingQueue<Product> products, String name) {
		this.cook = cook;
		this.products = products;
		this.name = name;
	}

	public void consume(){
		try {
			Product product = products.take();
			System.out.println(name + " 消费" + product);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
		}
	}

	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {
				consume();// 500消费一个
				synchronized (cook) {
					if(products.size() == 0 && cook.isRest()){
						cook.setRest(false);
						cook.notifyAll();
						System.out.println("库存不够,厨师开始工作……");
					}
				}
				TimeUnit.MILLISECONDS.sleep(500);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("用户:" + name + "停止消费!");
		}
		
	}
}
public class Restaurant {
	private Cook cook;
	
	public Restaurant(Cook cook) {
		this.cook = cook;
	}

	public static void main(String[] args) throws InterruptedException {
		
		System.out.println("饭馆开门");
		ExecutorService exec = Executors.newCachedThreadPool();
		BlockingQueue<Product> products = new LinkedBlockingQueue<Product>();
		Cook cook = new Cook(products);
		Restaurant restaurant = new Restaurant(cook);
		exec.execute(cook);
		for(int i = 0; i < 5; i++){
			exec.execute(new Customer(cook,products, "用户" +  i));
		}
		
		TimeUnit.SECONDS.sleep(2);//模拟五秒
		exec.shutdownNow();
		System.out.println("饭馆关门");
	}

}

 

 Output:

 

饭馆开门

生产了产品0

用户0 消费产品0

生产了产品1

用户1 消费产品1

生产了产品2

用户2 消费产品2

生产了产品3

用户4 消费产品3

生产了产品4

用户3 消费产品4

生产了产品5

生产了产品6

生产了产品7

生产了产品8

生产了产品9

用户0 消费产品5

生产了产品10

用户1 消费产品6

生产了产品11

用户2 消费产品7

生产了产品12

用户4 消费产品8

生产了产品13

用户3 消费产品9

生产了产品14

生产了产品15

生产了产品16

生产了产品17

生产了产品18

生产了产品19

用户0 消费产品10

生产了产品20

用户1 消费产品11

生产了产品21

用户2 消费产品12

生产了产品22

用户4 消费产品13

生产了产品23

用户3 消费产品14

生产了产品24

有剩余产品,厨师休息…………

用户0 消费产品15

用户1 消费产品16

用户2 消费产品17

用户4 消费产品18

用户3 消费产品19

用户0 消费产品20

用户:用户2停止消费!

停止生产!

用户:用户1停止消费!

用户:用户0停止消费!

用户:用户3停止消费!

用户:用户4停止消费!

饭馆关门


 

1
3
分享到:
评论

相关推荐

    JAVA 多线程学习笔记

    2. `BlockingQueue`:队列实现的线程通信,如`ArrayBlockingQueue`、`LinkedBlockingQueue`,适合生产者消费者模式。 五、线程池 1. `ExecutorService`:Java 5引入的线程池接口,通过`Executors`工厂类创建不同...

    java多线程笔记

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

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

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

    java多线程学习笔记

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

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

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

    JUC学习笔记(Java多线程)

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

    Java并发编程学习笔记.rar

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

    多线程学习笔记.docx

    生产者消费者模式是一种典型的线程同步场景,其中生产者线程负责生成数据,消费者线程负责消耗数据。生产者在数据准备好后通知消费者,消费者在数据未准备好时等待。这种模式通常借助于BlockingQueue(阻塞队列)来...

    java实战经典学习笔记

    ### Java实战经典学习笔记知识点概览 #### 一、Java概述及开发环境搭建 - **Java概述** - Java是一种广泛使用的高级编程语言,由Sun Microsystems于1995年发布。 - Java的设计目标是“一次编写,到处运行”,这...

    JAVA经典教材笔记

    - **线程操作案例—生产者和消费者** - 生产者-消费者模型:使用阻塞队列实现。 - 生产者-消费者模型的优点:解耦生产者与消费者。 - **线程生命周期** - 线程的状态:NEW、RUNNABLE、BLOCKED等。 - 线程状态...

    线程学习实例和笔记

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

    Java并发实践-学习笔记

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

    马士兵多线程训练营笔记

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

    Java多线程文章系列.pdf

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

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

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

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

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

    java学习笔记

    掌握如何创建线程(通过Thread类或实现Runnable接口)、线程同步(synchronized关键字、wait()和notify()方法)、线程通信(如生产者消费者模型)以及线程池(ExecutorService)等,可以提高程序的并发性能。...

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

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

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

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

    kafka学习笔记.doc

    afka的消费模式与消费者组Kafka提供了两种消费模式:单消费者模式和消费者组模式。单消费者模式中,一个消费者实例负责消费所有分区,适合小规模的低并发场景。而消费者组模式则是Kafka高并发、高可用的核心特性,多...

Global site tag (gtag.js) - Google Analytics