Java生产者消费者例子,大家看还有哪里可以改进? Java多线程 wait和notify运用 synchronized运用1.模拟商店 (进货/销售)Shop.java
package com.cloud.factory;
import java.util.ArrayList;
import java.util.List;
import com.cloud.pojo.Product;
/**
 * 模拟商店 (进货/销售)
 */
public class Shop {
private static int i = 0;
// 产品的容器;达到容器暂停生产,消费到0等待生产
private static List<Product> list;
static {
list = new ArrayList<Product>();
}
/**
 * 生产产品
 */
public synchronized void produ() {
if (list.size() >= 5) {
try {
System.out.println(this.getClass()+"--------------生产商品" + i
+ "时,达到了总数暂停生产-------");
this.wait();// 使当前生产产品的线程 进入休眠
} catch (InterruptedException e) {
System.out.println(e.toString());
e = null;
}
} // 生产商品
Product product = new Product();
product.setName("商品" + i+1);
list.add(product);
System.out.println(this.getClass()+"生产了商品---->" + product.getName() + "商品总数" + i+1);
System.out.println(this.getClass()+"容器容量" + list.size());
i++;
super.notify();
}
/**
 * 消费产品
 * @return
 */
public synchronized void cousu() {
if (list.size() == 0) {// 消费完时,挂起
System.out.println(this.getClass()+"+++++++++++++++++++++++商品消费完了.等待+++++++++++++++=");
try {
this.wait();//使当前消费产品的线程 进入休眠
} catch (InterruptedException e) {
System.out.println(e.toString());
e = null;
}
}
Product product = list.get(0);
list.remove(0);
System.out.println(this.getClass()+"消费者获得了商品-->" + product.getName());
System.out.println(this.getClass()+"容器容量" + list.size());
super.notify();
}
}
2.实体类Product.javapackage com.cloud.pojo;
/**
 * Product.java
 */
public class Product {
/**产品名称*/
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}3.消费者Cousumer.javapackage com.cloud.thread;
import java.util.Random;
import com.cloud.factory.Shop;
/**
 * 消费者
 */
public class Cousumer implements Runnable {
private Shop shop;// 要去消费的商店
public Cousumer(Shop shop) {
this.shop = shop;
}
public void run() {
while (true) {
try {
System.out.println(this.getClass()+" 开始消费...");
int couTime = new Random().nextInt(3000);//生成0-3000毫秒的随机数
Thread.sleep(couTime);
shop.cousu();
System.out.println(this.getClass()+" 消费了一件产品。耗时"+couTime+"毫秒。");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}4.生产者Producer.javapackage com.cloud.thread;
import java.util.Random;
import com.cloud.factory.Shop;
/**
 * 生产者   
 */
public class Producer implements Runnable {
private Shop shop;// 要去送货的商店
public Producer(Shop shop) {
this.shop = shop;
}
public void run() {
while (true) {
try {
System.out.println(this.getClass()+" 开始生产...");
int proTime = new Random().nextInt(3000);//生成0-3000毫秒的随机数
Thread.sleep(proTime);
shop.produ();
System.out.println(this.getClass()+" 生产了一件产品。耗时"+proTime+"毫秒。");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}5.测试客户端Client.javapackage com.cloud.test;
import com.cloud.factory.Shop;
import com.cloud.thread.Cousumer;
import com.cloud.thread.Producer;
/**
 * 测试客户端
 */
public class Client {
// 测试代码
public static void main(String[] args) {
Shop shop = new Shop();// 商店
Producer pro = new Producer(shop);
Cousumer cou = new Cousumer(shop);
new Thread(pro, "pro").start();
new Thread(cou, "cou").start();
}
}Java多线程wait和notify运用synchronized运用Java生产者消费者Thread

解决方案 »

  1.   

    开始学习Java多线程了,欢迎大家分享经验共同探讨
      

  2.   

    没细看代码,看到了一个使用不当的地方:
    一定要在循环中调用wait()方法。贴上JDK API中对wait方法的注意点:
    在没有被通知、中断或超时的情况下,线程还可以唤醒一个所谓的虚假唤醒 (spurious wakeup)。虽然这种情况在实践中很少发生,但是应用程序必须通过以下方式防止其发生,即对应该导致该线程被提醒的条件进行测试,如果不满足该条件,则继续等待。换句话说,等待应总是发生在循环中,如下面的示例:synchronized (obj) {
    while (<condition does not hold>)
    obj.wait(timeout);
    ... // Perform action appropriate to condition
         }
    原因详见<深入java虚拟机>第二版一书的344页
      

  3.   

    interface://实体接口
    public interface IEntity {
    public void on();
    public void off();
    }
    //命令接口
    public interface ICommand {
    public void OnExecute();
    public void OffExecute();
    public void setIEntity(IEntity entity);
    }
    //容器接口
    public interface IContainer {
    public void pushCommand(ICommand command);
    public ICommand popCommand();
    }具体实现:public class EntityImpl implements IEntity{
    //实体状态
    private boolean flag = true;

    @Override
    public void on() {
    this.flag = true;
    System.out.println("实体状态:  " + this.flag);
    }

    @Override
    public void off() {
    this.flag = false;
    System.err.println("实体状态: " + this.flag);
    }
    }public class CommandImpl implements ICommand{

    private IEntity entity = null; //实体

    public CommandImpl(EntityImpl entity){
    this.entity = entity;
    }

    @Override
    public void OffExecute() {
    entity.off();
    }
    @Override
    public void OnExecute() {
    entity.on();
    } @Override
    public void setIEntity(IEntity entity) {
    this.entity = entity;
    }

    }public class ContainerImpl implements IContainer{
    private static IContainer container = new ContainerImpl();

    //模拟栈
    private ICommand[] stack = null;
    private int index = 0;

    /**
     * 私有构造方法
     */
    private ContainerImpl(){ 
    this.stack = new ICommand[10];
    }

    /**
     * 获取容器
     * @return
     */
    public static IContainer getContainerInstance(){
    return container;
    }
    /**
     * push command
     */
    @Override
    public synchronized void pushCommand(ICommand command) {
    while(index == this.stack.length){
    try {
    super.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    this.stack[index] = command;
    ++this.index;
    System.out.print("+ [Thread:"+ Thread.currentThread().getName() + " 添加命令成功]");
    command.OnExecute();
    try {
    Thread.currentThread().sleep(1000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    super.notifyAll();
    } /**
     * pop command
     */
    @Override
    public synchronized ICommand popCommand() {
    while(index == 0){
    try {
    super.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    --this.index;
    ICommand command = this.stack[index];

    System.err.print("- [Thread:"+ Thread.currentThread().getName() + " 获取命令成功]");
    command.OffExecute();

    try {
    Thread.currentThread().sleep(1000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    super.notifyAll();
    return command;
    }
    }生产者:public class Producers_Thread implements Runnable{
    private IContainer container = null;


    public Producers_Thread(IContainer container){
    this.container = container;
    }
    @Override
    public void run() {
    while(true){
    this.container.pushCommand(new CommandImpl(new EntityImpl()));
    }
    }
    }消费者:public class Consumer_Thread implements Runnable{
    private IContainer container = null;


    public Consumer_Thread(IContainer container){
    this.container = container;
    }

    @Override
    public void run() {
    while(true){
    this.container.popCommand();
    }
    }

    }测试:public class Main {
    public static void main(String[] args){
    IContainer container = ContainerImpl.getContainerInstance();

    Thread pt_1 = new Thread(new Producers_Thread(container));
    pt_1.setName("pt_1");
    Thread pt_2 = new Thread(new Producers_Thread(container));
    pt_2.setName("pt_2");

    Thread ct_1 = new Thread(new Consumer_Thread(container));
    ct_1.setName("ct_1");
    Thread ct_2 = new Thread(new Consumer_Thread(container));
    ct_2.setName("ct_2");
    Thread ct_3 = new Thread(new Consumer_Thread(container));
    ct_3.setName("ct_3");

    pt_1.start();
    pt_2.start();

    ct_1.start();
    ct_2.start();
    ct_3.start();
    }
    }