`
ganshisheng
  • 浏览: 42533 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

线程---生产者消费者问题

阅读更多
    在开始之前先简单回顾一下生产者消费者问题:一群生产者在生产消息,并将此消息提供给消费者去消费。它们中间设了具有N个缓存区的缓冲池,生产者每次可将生产的消息放入一个缓存区内,消费者每次可将一个缓存区内的消息拿出来消费。但这个过程有两个条件:任何一方操作一个缓冲区时不能有其它同时对该缓冲区进行操作;只有当缓冲区还有空余,生产者才能生产,只有当缓冲区至少有一个产品,消费者才能从中取出来消费。这里两个条件分别对应了互斥和同步。



生产者与消费者模型中,要保证以下几点:
1 同一时间内只能有一个生产者生产
2 同一时间内只能有一个消费者消费
3 生产者生产的同时消费者不能消费
4 消息队列满时生产者不能继续生产
5 消息队列空时消费者不能继续消费



正文:

首先先建一个使用多线程的写的生产者消费者的通用类,在生产方法中(produce()),如果队列中已经有五个大饼,就提示消息,等待消费者消费大饼,否则往队列中添加大饼。在消费方法中(consume()),如果队列中没有大饼,则提示消息,等待生产者生产大饼,否则就删除一条大饼消息。
import java.util.ArrayList;
import java.util.List;

public class Stack {   
    List<Message> stack = new ArrayList<Message>();
    private int   MAX_MESSAGE_NUM = 5;   
    public Stack(){   
        System.out.println("大饼生产基地!");    
    }   
       
    //加上互斥锁   
    public synchronized void produce(Message message){   
        while( stack.size() == MAX_MESSAGE_NUM ){   
            try{   
                System.out.println(Thread.currentThread().getName() + " 队列满!等待消费...");   
                this.wait(); 
            }catch(InterruptedException e){   
            }   
        }   
        stack.add(message);
        System.out.println(Thread.currentThread().getName() + " 正在生产" + message.getContent() + " 当前大饼个数:" + stack.size());
        this.notify();    
    }   
       
    //加上互斥锁   
    public synchronized void consume(){   
        while(stack.size() == 0){   
            try{   
                System.out.println("队列空,无大饼,请等待...");   
                this.wait();  
            }catch(InterruptedException e){   
            }   
        }   
        Message message = stack.get(0);
        stack.remove(0);
        System.out.println(Thread.currentThread().getName() + " 正在消费"
       + message.getContent() + " ,当前大饼个数: " + stack.size());
        
        this.notify();    
    }   
       
}   


创建个消息对象。
public class Message {
	public static int id;
	public String content;
	public static int getId() {
		return id;
	}
	public static void setId(int id) {
		Message.id = id;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	
}


生产者类,主要产生消息,注意继承了Thread并实现了run,并且有一个对Stack实例的引用,主要调用了Stack的produce方法
class Producer extends Thread {
 
 private Stack stack;

 public Producer(Stack s){
  this.stack = s;
 }

 public void run (){
  while(true){
   Message message = new Message();
   message.setId(++ Message.id);
   message.setContent("大饼" + Message.id);
 
   stack.produce(message);
   try{
    sleep(100);
   }catch(Exception e){
    
   }
  }
 }
}


消费者类,主要消费消息,跟生产者是对称的,主要调用了Stack的consume方法。
class Consumer extends Thread {
 private Stack stack;
 
  Consumer(Stack stack) {
    this.stack = stack;
   }

   public void run() {
    while (true) {
     stack.consume();
     try {
      sleep(100);
     } catch (Exception e) {
     }

    }
   }
}


主类,主要构造出一个Stack并启动N个生产者和消费者。

public class ThreadTest {

 public static void main(String[] args) {

  Stack s = new Stack();

  Producer p1 = new Producer(s);
  Producer p2 = new Producer(s);
  Producer p3 = new Producer(s);
  
  Consumer c1 = new Consumer(s);
  Consumer c2 = new Consumer(s);
  Consumer c3 = new Consumer(s);
  
  Thread threadP1 = new Thread(p1, "thread-生产者--A");
  Thread threadP2 = new Thread(p2, "thread-生产者--B");
  Thread threadP3 = new Thread(p3, "thread-生产者--C");

  Thread threadC1 = new Thread(c1, "thread-消费者甲");
  Thread threadC2 = new Thread(c2, "thread-消费者乙");
  Thread threadC3 = new Thread(c3, "thread-消费者丙");
  
  threadP1.start();
  threadP2.start();
  threadP3.start();
  
  threadC1.start();
  threadC2.start();
  //threadC3.start();
 }
}


从以上这个例子,可以看出来,通过一个Stack,我们将一个对象的创建和执行分离开了(在生产者中创建,在消费者中执行,这种分离带来了极大的好处。比如将费时的执行分开之后提高了创建线程的响应性,并且它们之间的顺序实现了可控性,不用创建完了马上就执行,它们的分离使得可以分布式做创建和分离,从而出现了类似BMQ的消息中间件。
分享到:
评论

相关推荐

    用多线程同步方法解决生产者-消费者问题(操作系统课设

    生产者-消费者问题是操作系统中经典的问题之一,它是指在多线程环境下,多个生产者线程和消费者线程访问同一个共享缓冲区,导致缓冲区的数据混乱和不一致的问题。 在解决生产者-消费者问题时,需要使用同步机制来...

    Java多线程-生产者与消费者问题

    ### Java多线程-生产者与消费者问题 #### 一、生产者与消费者问题概览 **1.1 概要** 生产者与消费者问题是计算机科学中一个多线程同步的经典问题。它描述了两个线程如何共享有限资源的场景:一个是生产者...

    多线程代码 经典线程同步互斥问题 生产者消费者问题

    a: 创建一个线程 ...h: problem1 生产者消费者问题 (1生产者 1消费者 1缓冲区) problem1 more 生产者消费者问题 (1生产者 2消费者 4缓冲区) problem2 读者与写着问题 I: 信号量 semaphore 解决线程同步问题

    生产者-消费者的Linux多线程实现.pdf

    本文将详细地阐述 Linux 下利用互斥锁、条件变量、线程管理等相关函数实现多线程生产者-消费者问题,以提高资源利用率。 线程基本概念 线程是进程的一条执行路径,它包含独立的堆栈和 CPU 寄存器状态,每个线程...

    线程同步--生产者消费者问题

    在Java编程中,"线程同步--生产者消费者问题"是一个经典的多线程问题,它涉及到如何有效地在多个线程之间共享资源。这个问题通常用于演示和理解线程间的协作机制,如互斥锁、条件变量等。在此,我们将深入探讨这个...

    用多线程同步方法解决生产者-消费者问题

    生产者-消费者问题是多线程同步的一个经典案例,主要探讨如何在并发环境下,确保生产者进程和消费者进程之间正确地共享资源,避免数据竞争和死锁。在这个问题中,生产者进程负责创建产品并将产品放入缓冲区,而消费...

    生产者-消费者多线程处理

    在本场景中,我们关注的是一个经典的多线程问题——"生产者-消费者"模式。这个模式是解决资源管理与同步问题的一个有效策略,它在操作系统、并发编程和分布式系统等领域广泛应用。 生产者-消费者模型涉及到两个主要...

    Java多线程实现生产者消费者

    本示例中的“生产者-消费者”模型是一种经典的多线程问题,它模拟了实际生产环境中的资源分配与消耗过程。下面我们将详细探讨如何在Java中实现这个模型。 首先,我们要理解生产者-消费者模型的基本概念。在这个模型...

    java多线程实现生产者和消费者

    在并发编程中,"生产者-消费者"模式是一种经典的解决问题的范式,用于协调两个或更多线程间的协作,其中一部分线程(生产者)生成数据,另一部分线程(消费者)消费这些数据。 生产者-消费者模型的核心在于共享资源...

    Java线程间的通信----生产者消费者模型

    生产者消费者模型是一种经典的线程同步问题,它模拟了实际生活中的生产过程和消费过程,使得生产者线程可以将数据生产出来,而消费者线程则负责消耗这些数据,两者之间通过共享数据结构进行协同工作。 生产者消费者...

    线程问题生产者消费者流程图

    生产者消费者流程图; 生产者消费者流程图。

    多线程同步方法解决生产者-消费者问题(linux线程实现)

    设计要求:(1)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费者线程的标识符.(2)生产者和消费者各有两个以上.(3)多个生产者或多个消费者之间须有共享对缓冲区...

    多线程--生产者消费者问题[1][收集].pdf

    【生产者消费者问题】是多线程编程中的经典问题,主要涉及到进程同步和互斥的概念。在操作系统中,生产者负责生成数据,而消费者则负责消耗这些数据。两者通过一个有限大小的缓冲区进行交互,当缓冲区满时,生产者...

    Linux c语言多线程实现生产者/消费者问题

    以生产者/消费者问题为例来阐述Linux线程的控制和通信。一组生产者线程与一组消费者线程通过缓冲区发生联系。生产者线程将生产的产品送入缓冲区,消费者线程则从中取出产品。缓冲区有N 个,是一个环形的缓冲池。 ...

    多线程实现生产者---消费者模型

    在本场景中,我们关注的是"生产者-消费者模型",这是一个经典的并发问题,通常用于展示线程间的协作与同步。这个模型是基于一个假设:有一个缓冲区,生产者线程负责往里面放入产品,而消费者线程则负责取出并消费...

    12.2 Qt5多线程:使用信号量实现生产者和消费者

    生产者-消费者问题是并发编程中的一个经典模型,它描述了两个或多个线程之间的协作,其中一个或多个线程(生产者)负责生成数据,而其他线程(消费者)则负责处理这些数据。在实际应用中,这可以对应于例如数据生成...

    多线程简易实现生产者消费者模式

    生产者消费者模式是一种经典的多线程同步问题解决方案,它源于现实世界中的生产流水线,用于描述生产者(Producer)和消费者(Consumer)之间的协作关系。在这个模式中,生产者负责生成产品并放入仓库,而消费者则从...

    用多进程同步方法演示“生产者-消费者”问题

    1、设计目的:通过研究Linux的进程机制和信号量,实现生产者消费者问题的并发控制。 2、说明:有界缓冲区内设有20个存储单元,放入取出的产品设定为1-20个整数。 3、设计要求: 生产者和消费者进程的数目不固定,可...

    JAVA实现线程间同步与互斥生产者消费者问题

    本项目通过一个生产者消费者问题的实例,展示了如何在Java中实现线程间的同步与互斥。 生产者消费者问题是经典的并发问题之一,它涉及到两个类型的线程:生产者和消费者。生产者负责生成数据(产品),而消费者则...

    利用线程实现生产者消费者问题

    生产者消费者问题是计算机科学中的一个经典问题,主要用于描述并发环境下多个线程之间如何共享有限资源的问题。在这个问题中,“生产者”负责生成数据并将其放入公共缓冲区中,“消费者”则负责从缓冲区取出数据进行...

Global site tag (gtag.js) - Google Analytics