多线程之生产者与消费者问题

之前感觉非常easy,可是有一次面试让我在纸上写,竟然没写对丢人啊。

生产者消费者问题(Producer-consumer problem):生产者不断地生产产品。消费者取走生产者生产的产品。生产者生产出产品后将其放到一个区域之中。消费者从这个地方去除数据。

涉及的问题:要保证生产者不会在缓冲区满时增加数据,消费者也不会在缓冲区中空时消耗数据。

主要涉及:多线程的同步问题。

1、如果生产者线程刚向数据存储空间加入了产品的名称,还没有加入产品的内容,程序就切到了消费者的线程,消费这的

线程将吧产品的名称和上一个产品的内容联系到了一起。

2、生产者放了若干次的产品,消费者才開始取产品,或者是,消费者去玩一个产品后,还没等待生产者生产新的产品,有

反复的去除已经去过的产品。

其生产者消费者问题程序实现例如以下:

一、产品:

package andy.thread.test;

/**
 * @author andy
 * @version:2015-3-20 上午10:09:42
 *
 *
 */

public class Product {

	private String pName;

	private String pContent;

	private boolean flag; // 此为产品的标记 true为已有产品 false为没有产品

	//生产
	public synchronized void put(String pName, String pContent) {

		if (flag) {// 假设有产品。等待消费
			try {
				super.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		this.setpName(pName);

		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		this.setpContent(pContent);
		System.out.println("生产产品");

		this.flag = true; // 标记为以生产,唤醒消费
		super.notify();
	}

	//消费
	public synchronized void romve() {

		if (!flag) { // 没有产品时等待
			try {
				super.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		System.out
				.println("消费:" + this.getpName() + "---" + this.getpContent());
		this.flag = false; // 已消费,能够进行生产了

		super.notify();

	}

	public String getpName() {
		return pName;
	}

	public void setpName(String pName) {
		this.pName = pName;
	}

	public String getpContent() {
		return pContent;
	}

	public void setpContent(String pContent) {
		this.pContent = pContent;
	}

}

二、生产者

package andy.thread.test;

import java.util.concurrent.TimeUnit;

/**
 * @author andy
 * @version:2015-3-20 上午11:05:53
 *
 *
 */

public class Producer implements Runnable {

	private Product product = null;

	public Producer(Product product) {
		this.product = product;
	}

	@Override
	public void run() {
		for (int i = 0; i < 50; i++) {

			try {
				TimeUnit.SECONDS.sleep(5);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			product.put("产品" + i, i + "");
		}

	}

}

三、消费者

package andy.thread.test;

import java.util.concurrent.TimeUnit;

/**
 * @author andy
 * @version:2015-3-20 上午10:56:18
 *
 *
 */

public class Consumer implements Runnable{

	private Product product = null;

	public Consumer(Product product){
		this.product = product;
	}

	@Override
	public void run() {

		for (int i = 0; i < 50; i++) {

			try {
				TimeUnit.SECONDS.sleep(5);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			this.product.romve();

		}

	}

}

測试:

package andy.thread.test;

/**
 * @author andy
 * @version:2015-3-20 上午11:12:25
 *
 *
 */

public class ConsumerProducerTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		Product product = new Product();
		Producer producer = new Producer(product);
		Consumer consumer = new Consumer(product);

		new Thread(producer).start();
		new Thread(consumer).start();

	}

}

结果例如以下:

时间: 2024-12-28 21:36:16

多线程之生产者与消费者问题的相关文章

java_多线程_生产者与消费者(并发协作)

对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一样,Hello World!都是最经典的例子. 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了.对于此模型,应该明确一下几点:1.生产者仅仅在仓储未满时候生产,仓满则停止生产.2.消费者仅仅在仓储有产品时候才能消费,仓空则等待.3.当消费者发现仓储没产品可消费时候会通知生产者生产.4.生产者在生产出可消费产品时候,应该通知等待的消费者去消费. packa

java多线程实现生产者与消费者---经典问题

前几天老师领着学习了一下单线程和多线程的题目. 这里是操作系统中非常经典的题目,生产者和消费者的题,这里涉及的是仓库, 只有一个人(生产者或消费者)进入,另一个人只有等待. 这里的重点是关于传值的问题.一定要保持一致,不然,对于存和取 的对象,就可能出现多个. //========================================================================// 仓库类 //====================================

多线程--简单生产者与消费者(Lock锁)

前两篇的生产者与消费者(多线程)运用的是synchronized进行同步锁的,本次将运用JDK1.5提供的Lock锁. 它 将synchronized替换成了Lock将Object中的wait notify notifyAll替换成了Condition对象, Condition可以被Lock获取, 可以创建多个Condition对象,只唤醒对方操作. 具体代码如下: package cn.zz; import java.util.concurrent.locks.Condition;import

Java多线程的生产者与消费者模型,线程间的通信

java多线程中的生产者与消费者模式:首先有一个阻塞队列,生产者将生产的东西放到队列里,消费者再从队列中取.当队列中的东西数量达到其容量就发生阻塞. import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import jav

java 22 - 16 多线程之生产者和消费者的问题

生产者和消费者问题的描述图 通过上图,我们可以发现: 生产者和消费者使用的都是同一个资源(肉包子) 所以,当使用线程的时候,这两类的锁也是同一把锁(为了避免出现线程安全问题) 例子:学生信息的录入和获取 * 资源类:Student * 设置学生数据:SetThread(生产者) * 获取学生数据:GetThread(消费者) * 测试类:StudentDemo * 资源类:Student 1 public class Student { 2 3 String name; 4 int age; 5

Java:多线程之生产者与消费者

要求:用两个线程模拟存票.售票过程.但要求每存入一张票,就售出一张票,售出后,再存入,直到售完为止. 用到的知识点:线程等待.唤醒.可能的线程中断异常 下面的方式一和方式二采用的是唤醒所有等待的线程,即wait()和notify()方法 方式一:继承Thread class Tickets //定义(资源)票类 { protected int size;//总票数 int number=0; //票号 Boolean available=false;//表示当前是否有票可售 public Tic

Linux下用条件变量实现多线程间生产者与消费者问题

一. 线程间的同步还有这样一种情况:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行.在pthread库中通过条件变量(Condition Variable)来阻塞等待某个条件,或者唤醒等待这个条件的线程.Condition Variablepthread_cond_t类型的变量表,可以这样初始化和销毁: 返回值:成功返回0,失败返回错误号. 一个Condition Variable总是和一个Mutex搭配使

多线程之生产者和消费者模式

package com.git.base.thread.productandconsumer; /** * 核心实现: * 生产者消费者模式: * 生产一个,消费一个,如果生产未被消费,那么就等待消费后再生产 * 如果消费后,没有下一个生产的,就等待生产后在消费 * <p>Title: DoMain.java</p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2016</p&g

多线程操作实例——生产者与消费者

面对多线程学习生产者与消费者是最基本的实例 对于java后端开发的人员必须要掌握,还有考研考试计算机操作系统的同鞋. 下面是三个实例对于生产者与消费者的的例子,层层递进,逐步解决问题. 问题:生产者——设置信息名字name,和内容content 消费者——负责取出设置的信息. 一.基本实现 由于线程的不确定性可能出现以下问题: (1)消费者取出的信息不匹配,即不是由同一个生产者设置的信息 (2)生产者生产了多个信息,消费者才开始取出信息,或消费者取出的重复的信息. 上面的问题下面会逐一解决,下面