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