`

java多线程 消费者-生产者

阅读更多

java多线程一般都会讲消费者-生产者模型

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

参考了下网上一个代码实例http://www.talented.com.cn/archives/2007/5/16_141.html  发现作者写得有问题 修改了一些代码  现在ok了

----------------------------------------------------Message类

package com.example.test;

public class Message {
 
 public static int id;
 public String content;

 public String getContent() {
  return content;
 }

 public void setContent(String content) {
  this.content = content;
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  Message.id = id;
 }
}

----------------------------------------------------Queue类

package com.example.test;

import java.util.ArrayList;
import java.util.List;

public class Queue {
 List<Message> queue = new ArrayList<Message>();

 /** 队列中message对象的最大值,默认为5 */
 int maxMessageNum = 5;

 public synchronized void produce(Message message) {

  this.notifyAll();
  while (queue.size() == maxMessageNum) {
   System.out.println(Thread.currentThread().getName()
     + "  队列满!等待中。。。");
   try {
    this.wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
  queue.add(message);
  System.out.println(Thread.currentThread().getName() + "正在生产"
    + message.getContent() + "。。。  ,当前个数:" + getCount());

 }

 public synchronized void consume() {

  this.notifyAll();
  while (queue.size() == 0) {
   System.out.println(Thread.currentThread().getName()
     + "  队列空!等待中。。。");
   try {
    System.out.println("begin!");
    wait();
    System.out.println("end!");
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }

  Message message = queue.get(0);
  queue.remove(0);
  System.out.println(Thread.currentThread().getName() + "正在消费"
    + message.getContent() + "。。。 ,当前个数: " + getCount());

 }

 public synchronized int getCount() {
  return queue.size();
 }
}


----------------------------------------------------Test类

package com.example.test;

public class Test {

 public static void main(String[] args) {

  Queue Q = new Queue();

  Producer wQ1 = new Producer(Q);
  Producer wQ2 = new Producer(Q);
 
  Consumer rQ1 = new Consumer(Q);
  Consumer rQ2 = new Consumer(Q);
  Consumer rQ3 = new Consumer(Q);
 
  Thread threadWQ1 = new Thread(wQ1, "thread-wQ1");
  Thread threadWQ2 = new Thread(wQ2, "thread-wQ2");

  Thread threadRQ1 = new Thread(rQ1, "thread-rQ1");
  Thread threadRQ2 = new Thread(rQ2, "thread-rQ2");
  Thread threadRQ3 = new Thread(rQ3, "thread-rQ3");
 
  threadWQ1.start();
  threadWQ2.start();
 
  threadRQ1.start();
  threadRQ2.start();
  threadRQ3.start();
 }
}

class Producer extends Thread {

 private Queue queue;

 Producer(Queue queue) {
  this.queue = queue;
 }

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

 }
}

class Consumer extends Thread {
 private Queue queue;

 Consumer(Queue queue) {
  this.queue = queue;
 }

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

  }
 }
}

分享到:
评论
17 楼 newko 2010-03-27  
sw1982 写道
LinkedBolockQueue

生产者和消费者(BolockingQueue Implements)
http://compous-cn.iteye.com/blog/625888
16 楼 banfry 2010-03-16  
超级潜水艇 写道
asialee 写道
liwenso 写道
banfry 写道
问下各位,“  public synchronized void produce(Message message) {”
该方法锁定的资源是“message”还是“queue”?


锁定的是这个produce方法


这个应该是锁定的是Queue对象吧,要执行produce方法,必须要拿到Queue对象的锁。

锁对象,有人还没有搞清楚同步的对象是哪个哦!


锁定"queue",会不会将message也附带锁上呢,毕竟message存放在queue里面?
15 楼 sw1982 2010-03-15  
LinkedBolockQueue
14 楼 tianmo2008 2010-03-15  
liwenso 写道
banfry 写道
问下各位,“  public synchronized void produce(Message message) {”
该方法锁定的资源是“message”还是“queue”?


锁定的是这个produce方法

锁对象的,锁方法的话,java的同步就没意义了.
13 楼 超级潜水艇 2010-03-15  
asialee 写道
liwenso 写道
banfry 写道
问下各位,“  public synchronized void produce(Message message) {”
该方法锁定的资源是“message”还是“queue”?


锁定的是这个produce方法


这个应该是锁定的是Queue对象吧,要执行produce方法,必须要拿到Queue对象的锁。

锁对象,有人还没有搞清楚同步的对象是哪个哦!
12 楼 asialee 2010-03-15  
liwenso 写道
banfry 写道
问下各位,“  public synchronized void produce(Message message) {”
该方法锁定的资源是“message”还是“queue”?


锁定的是这个produce方法


这个应该是锁定的是Queue对象吧,要执行produce方法,必须要拿到Queue对象的锁。
11 楼 liwenso 2010-03-15  
banfry 写道
问下各位,“  public synchronized void produce(Message message) {”
该方法锁定的资源是“message”还是“queue”?


锁定的是这个produce方法
10 楼 asialee 2010-03-15  
没有代码高亮,也欢迎大家指正。
9 楼 asialee 2010-03-15  
下面的是我写的:
import java.util.ArrayList;
import java.util.List;


public class ProductQueue {
private List<Product> products;

private int maxSize;

public ProductQueue(int maxSize){
this.maxSize = maxSize;
products = new ArrayList<Product>(maxSize);
}

public synchronized void addProdcut(Product product){
while(isFull()){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
products.add(product);
System.out.println("Produce:" + product.getId() + " " + product.getMadeDate());
notifyAll();
}

public synchronized void removeProduct(){
while(isEmpty()){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Product product = products.get(products.size() - 1);
products.remove(product);
System.out.println("Consume:" + product.getId() + " " + product.getMadeDate());
notifyAll();
}



public synchronized boolean isFull(){
boolean isFull =  products.size() == maxSize;
if(isFull){
System.out.println("The queue is full.");
}
return isFull;
}

public synchronized boolean isEmpty(){
boolean isEmpty = products.size() <= 0;
if(isEmpty){
System.out.println("The queue is empty.");
}
return isEmpty;
}
}



public class Consumer implements Runnable{
private ProductQueue queue;

public Consumer(ProductQueue queue){
this.queue = queue;
}

@Override
public void run() {
while(true){
queue.removeProduct();
try {
Thread.sleep(100l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

}


import java.util.Date;


public class Producer implements Runnable{
private static int id;
private ProductQueue queue;

public Producer(ProductQueue queue){
this.queue = queue;
}

@Override
public void run() {
while(true){
Product product = new Product(id++,new Date());
queue.addProdcut(product);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

}


import java.util.Date;


public class Product {
private int id;
private Date madeDate;

public Product(int id, Date madeDate){
this.id = id;
this.madeDate = madeDate;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public Date getMadeDate() {
return madeDate;
}

public void setMadeDate(Date madeDate) {
this.madeDate = madeDate;
}

}



public class ThreadMain {
public static void main(String[] args) {
ProductQueue queue = new ProductQueue(50);

for(int i = 0; i < 10; i++){
Producer producer = new Producer(queue);
new Thread(producer).start();
}

for(int i = 0; i < 10; i++){
Consumer consumer = new Consumer(queue);
new Thread(consumer).start();
}
}
}
8 楼 banfry 2010-03-15  
问下各位,“  public synchronized void produce(Message message) {”
该方法锁定的资源是“message”还是“queue”?
7 楼 p_x1984 2010-03-15  
谢谢各位的提醒!
6 楼 lzmhehe 2010-03-15  
看看jdk的BlockQueue
两年前我也自己实现生产消费
后来发现有现成的东西
5 楼 hmilylxs 2010-03-14  
asialee 写道
为什么在consume方法和produce方法开始的时候要调用 this.notifyAll(); 这个应该是生产者在生产完产品后调用通知其他线程,同样消费者在消费完产品后也要调用 this.notifyAll();方法来通知其他线程,为什么一上来调用它呢?


楼上有道理,我认为在consume和produce的结尾分别获得producer和consumer的锁,然后notify它们。在方法一开始唤醒不知道有什么意义。
4 楼 nishizhutou 2010-03-13  
<div class="quote_title">p_x1984 写道</div>
<div class="quote_div">
<p>java多线程一般都会讲消费者-生产者模型<br><br>生产者与消费者模型中,要保证以下几点:<br>1 同一时间内只能有一个生产者生产<br>2 同一时间内只能有一个消费者消费<br>3 生产者生产的同时消费者不能消费<br>4 消息队列满时生产者不能继续生产<br>5 消息队列空时消费者不能继续消费</p>
<p> </p>
<p>---------------------------------------------</p>
<p>除了4和5,其他都不是必要条件.实际上,更多的生产者消费者应用都不遵循1,2,3.<br></p>
</div>
<p> </p>
3 楼 asialee 2010-03-13  
为什么在consume方法和produce方法开始的时候要调用 this.notifyAll(); 这个应该是生产者在生产完产品后调用通知其他线程,同样消费者在消费完产品后也要调用 this.notifyAll();方法来通知其他线程,为什么一上来调用它呢?
2 楼 mercyblitz 2010-03-13  
不错,不过synchronized 关键字范围过大
1 楼 agao1985 2010-03-13  
做开发一年了 没写过一个线程类

相关推荐

    Java多线程 生产者-消费者模式

    总之,Java中的生产者-消费者模式是多线程编程中解决数据共享和同步问题的有效手段,通过合理利用`BlockingQueue`等并发工具类,我们可以构建高效、稳定的多线程应用。在开发过程中,了解和掌握这种模式有助于提高...

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

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

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

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

    Java 多线程课程的代码及少量注释.zip

    Java 多线程主题1- Java 多线程启动线程2- Java 多线程Volatile – 基本线程通信3- Java 多线程同步4- Java 多线程锁对象5- Java 多线程线程池6- Java 多线程倒计时闩锁7- Java 多线程生产者-消费者8- Java 多线程...

    java多线程经典模型生产者消费者

    java多线程经典模型生产者消费者java多线程经典模型生产者消费者java多线程经典模型生产者消费者java多线程经典模型生产者消费者java多线程经典模型生产者消费者java多线程经典模型生产者消费者java多线程经典模型...

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

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

    Java多线程编程总结

    Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 Java线程:新特征-有返回值的线程 Java线程:新特征-锁(上) Java线程:新特征-锁(下) Java...

    java多线程例子-生产者消费者

    在本示例中,“java多线程例子-生产者消费者”旨在展示如何利用多线程来实现生产者和消费者模式。这种模式是并发编程中的经典设计模式,用于协调生产数据和消费数据的两个不同线程。 生产者消费者模式的基本概念是...

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

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

    java多线程(生产者与消费者)

    总结来说,“java多线程(生产者与消费者)”是关于如何在Java中使用同步、线程间通信和共享资源来实现高效且安全的并发编程。通过理解并熟练应用这些概念和工具,开发者可以构建出能够充分利用多核处理器能力的高...

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

    总的来说,理解和掌握生产者消费者问题及其解决策略是Java多线程编程的重要部分,这不仅有助于编写高效、可靠的并发代码,也是提升软件设计能力的关键一步。通过不断实践和学习,开发者能够更好地应对复杂的并发场景...

    java实现多线程经典模型生产者消费

    java实现多线程经典模型生产者消费java实现多线程经典模型生产者消费java实现多线程经典模型生产者消费java实现多线程经典模型生产者消费java实现多线程经典模型生产者消费java实现多线程经典模型生产者消费java实现...

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

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

    java多线程实现生产者消费者关系

    在实际应用中,我们常常会遇到一种典型的多线程问题——生产者消费者模型。这个模型描述了两种类型的线程:生产者线程负责创建或生产资源,而消费者线程则负责消耗这些资源。在Java中,我们可以利用同步机制来实现...

    java多线程_消费者与生产者模型

    在Java多线程编程中,消费者-生产者模型是一种经典的线程间通信模式,用于解决多线程环境下的数据共享问题。该模型涉及到两个主要的角色:生产者(Producer)和消费者(Consumer)。生产者负责创建数据,而消费者则...

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

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

    【IT十八掌徐培成】Java基础第08天-04.多线程-生产者-消费者.zip

    通过学习和实践"生产者-消费者"模型,开发者能够更好地理解和掌握Java多线程的精髓,为构建高并发、高效率的应用打下坚实的基础。在实际项目中,这种模型常被用于实现缓存管理、消息队列以及数据库连接池等场景。

    java多线程实现生产者消费者问题

    用java多线程,实现生产者消费者同步和互斥的问题,操作系统中的经典问题

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

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

Global site tag (gtag.js) - Google Analytics