线程同步–生产者与消费者模式
来源:互联网 发布:对焦算法 编辑:程序博客网 时间:2024/05/23 16:21
生产者与消费者模式简单介绍:
生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来
以示例来说明问题:
以下程序参考至: http://www.iteye.com/topic/256991
首先是产品类:
Java代码 收藏代码
package consumerandproducter; /** * 单纯的产品类 * @author google * */ public class Product { private int productId=0; public Product(int id){ this.productId=id; } public int getProductId() { return productId; } public String toString(){ return "product "+productId; } }
再是仓库(缓冲区):
Java代码 收藏代码
package consumerandproducter; /** * 模拟缓冲区,以栈为数据结构,先进后出 * @author google * */ public class StoreHouse { private int base=0; private int top=0; private Product[] products=new Product[10]; /** * 入栈 * @param product */ public synchronized void push (Product product) { while(top==products.length){ //当前的线程已经放弃对资源的占有,唤醒已经被wait的线程,唤醒的线程由JVM决定,不按优先级确定 notify(); try { System.out.println("仓库已满,正在等待消费……"); wait();//此线程处于等待状态 } catch (Exception e) { e.printStackTrace(); } } products[top]=product; top++; } /** * 出栈 * @return */ public synchronized Product pop(){ Product product=null; while(top==base){ notify(); try { System.out.println("仓库已空,正在等待生产……"); wait(); } catch (Exception e) { e.printStackTrace(); } } top--; product=products[top]; products[top]=null; return product; } }
接着是消费者:
Java代码 收藏代码
package consumerandproducter; public class Consumer implements Runnable { private String consumerName; //保留有缓冲区对象的引用,以便消费产品 private StoreHouse storeHouse; public Consumer(String consumerName, StoreHouse storeHouse) { this.consumerName = consumerName; this.storeHouse = storeHouse; } public void run() { while(true){ System.out.println("消费者"+consumerName+"已经消费"+storeHouse.pop()); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } public String getConsumerName() { return consumerName; } public void setConsumerName(String consumerName) { this.consumerName = consumerName; } }
然后是生产者:
Java代码 收藏代码
package consumerandproducter; /** * 生产者类 * @author google * */ public class Producter implements Runnable { private String producterName; // 保留有缓冲区对象的引用,以便将生产的产品放入缓冲区 private StoreHouse storeHouse; public Producter(String producterName, StoreHouse storeHouse) { this.producterName = producterName; this.storeHouse = storeHouse; } public String getProducterName() { return producterName; } public void setProducterName(String producterName) { this.producterName = producterName; } public void producterProduct(){ //生产产品,并放入到仓库中 int i=0; while(true){ i++; Product product=new Product(i); storeHouse.push(product); System.out.println(producterName+"生产了"); try { Thread.sleep(2000); } catch (InterruptedException e) { return; } } } public void run() { producterProduct(); } }
测试类:
Java代码 收藏代码
package consumerandproducter; import sun.security.krb5.internal.crypto.t; public class Test { public static void main(String[] args) { StoreHouse storeHouse=new StoreHouse(); Producter producter=new Producter("生产者",storeHouse); Consumer consumer=new Consumer("消费者",storeHouse); Thread t1=new Thread(producter); Thread t2=new Thread(consumer); t1.start(); t2.start(); /** * ~输出(随机抽取输出,每次测试的结果可能都有稍许不同): * 生产者生产了 消费者消费者已经消费product 1 生产者生产了 消费者消费者已经消费product 2 生产者生产了 消费者消费者已经消费product 3 生产者生产了 消费者消费者已经消费product 4 ........... 仓库已空,正在等待生产…… 生产者生产了 生产者生产了 生产者生产了 生产者生产了 ......... 仓库已满,正在等待消费…… 消费者消费者已经消费product 14 消费者消费者已经消费product 13 消费者消费者已经消费product 12 消费者消费者已经消费product 11 消费者消费者已经消费product 10 ...... */ } }
小结:
此问题主要是考察java间多线程通信与资源同步, 其中主要是对于notify与wait方法的使用上,还有对于线程间资源的共享,利用synchronized关键字,对共享资源的锁定,以达到线程同步的效果。
阅读全文
0 0
- 线程同步–生产者与消费者模式
- 同步线程--生产者与消费者模式
- 线程同步--生产者消费者模式
- 进程与线程,同步与死锁,生产者消费者模式
- 生产者消费者模式的线程同步问题
- 生产者消费者模式(同步线程)
- 线程同步中的“生产者和消费者”模式
- Qt之线程同步(生产者消费者模式
- Qt之线程同步(生产者消费者模式
- 消费者与生产者线程同步程序
- 线程同步(消费者与生产者)
- C#生产者与消费者问题 线程同步
- 线程同步-生产者与消费者问题
- 线程同步:生产者与消费者模型
- 生产者、消费者 线程同步
- 线程同步--生产者消费者
- java线程通信 生产者与消费者模式
- java线程之生产者与消费者模式
- [LeetCode] Design Twitter
- ruby,gem,安装cocoapods
- Erlang:[笔记二,构建工具rebar之发布应用]
- jsonp跨域格式例子
- 关于 Java 数组的 12 个最佳方法
- 线程同步–生产者与消费者模式
- numpy数组广播详解
- 阿里云的Linux中,express创建的服务器遇到的坑
- docker在web开发中得使用流程是怎样的?
- Android6.0+解决getColor()方法过时
- java 求1+2!+3!+...+20!的和
- CodeVs1039[数的划分]
- 创建podsepc
- Volley的简单使用