生产者消费者模型是多线程中最常见的模型,有着广泛的应用。其主要目的是实现一种动态的平衡,让生产者消费者和谐共处,获得最大化的执行效率。
所说的动态平衡其实就是生产者与消费者协作控制仓储,让消费者不至于缺货,也不能导致不合理不和谐的库存。
生产者消费者实现最简单的方式是通过java5之后的线程池来实现,下面的例子很粗糙,但是能良好运行。
在实际应用中,可以基于数据库,加上复杂逻辑,实现更强悍的后台处理程序,目前基于此模型构建的后台程序良好运行,处理效果极佳。
/** 
* 消费者 

* @author leizhimin 12-10-23 下午4:10 
*/ 
public class MyTask implements Runnable{ 
        private long id;

public MyTask(long id) { 
                this.id = id; 
        }

@Override 
        public void run() { 
                try { 
                        Thread.sleep(100L); 
                } catch (InterruptedException e) { 
                        e.printStackTrace(); 
                } 
                System.out.println("\t"+Thread.currentThread().getName()+":"+id); 
        } 
}

import javax.swing.plaf.metal.MetalBorders; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ThreadPoolExecutor;

/** 
* 总调度程序 (包括协作生产) 

* @author leizhimin 12-10-23 下午4:18 
*/ 
public class TaskPool extends Thread { 
        private String poolname; 
        private ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);

public TaskPool(String poolname) { 
                this.poolname = poolname; 
        }

@Override 
        public void run() { 
                System.out.println(poolname + ":池中的当前线程数getPoolSize()=" + pool.getPoolSize()); 
                int i = 0; 
                while(true){ 
                        int x = pool.getQueue().size(); 
//                        System.out.println("返回核心线程数="+pool.getCorePoolSize()); 
                        System.out.println("返回此执行程序使用的任务队列="+pool.getQueue().size()); 
                        if(x>=5) 
                                try { 
                                        Thread.sleep(10L); 
                                        continue; 
                                } catch (InterruptedException e) { 
                                        e.printStackTrace(); 
                                } 
                        System.out.println(poolname + "该加入任务了");            //生产过程 
                        for(int k =i+10;i<k;i++){ 
                                pool.submit(new MyTask(i)); 
                        } 
                } 
        }

public static void main(String[] args) { 
                 new TaskPool("pool1").start(); 
        } 
}

E:\jdk1.6.0_33\bin\java -Didea.launcher.port=7534 -Didea.launcher.bin.path=C:\IDEA11.1.3\bin -Dfile.encoding=UTF-8 -classpath E:\jdk1.6.0_33\jre\lib\charsets.jar;E:\jdk1.6.0_33\jre\lib\deploy.jar;E:\jdk1.6.0_33\jre\lib\javaws.jar;E:\jdk1.6.0_33\jre\lib\jce.jar;E:\jdk1.6.0_33\jre\lib\jsse.jar;E:\jdk1.6.0_33\jre\lib\management-agent.jar;E:\jdk1.6.0_33\jre\lib\plugin.jar;E:\jdk1.6.0_33\jre\lib\resources.jar;E:\jdk1.6.0_33\jre\lib\rt.jar;E:\jdk1.6.0_33\jre\lib\ext\dnsns.jar;E:\jdk1.6.0_33\jre\lib\ext\localedata.jar;E:\jdk1.6.0_33\jre\lib\ext\sunjce_provider.jar;E:\jdk1.6.0_33\jre\lib\ext\sunmscapi.jar;E:\jdk1.6.0_33\jre\lib\ext\sunpkcs11.jar;G:\testprojects\testpool\out\production\testpool;C:\IDEA11.1.3\lib\idea_rt.jar com.intellij.rt.execution.application.AppMain TaskPool 
pool1:池中的当前线程数getPoolSize()=0 
返回此执行程序使用的任务队列=0 
pool1该加入任务了 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
  pool-1-thread-1:0 
  pool-1-thread-2:1 
  pool-1-thread-5:4 
  pool-1-thread-4:3 
  pool-1-thread-3:2 
返回此执行程序使用的任务队列=0 
pool1该加入任务了 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
  pool-1-thread-1:5 
  pool-1-thread-5:7 
  pool-1-thread-2:6 
  pool-1-thread-3:9 
  pool-1-thread-4:8 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
  pool-1-thread-1:10 
返回此执行程序使用的任务队列=4 
pool1该加入任务了 
返回此执行程序使用的任务队列=14 
  pool-1-thread-5:11 
  pool-1-thread-4:14 
  pool-1-thread-3:13 
  pool-1-thread-2:12 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
  pool-1-thread-1:15 
  pool-1-thread-4:17 
  pool-1-thread-3:18 
  pool-1-thread-2:19 
  pool-1-thread-5:16 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
  pool-1-thread-1:20 
  pool-1-thread-2:23 
  pool-1-thread-5:24 
  pool-1-thread-3:22 
  pool-1-thread-4:21 
返回此执行程序使用的任务队列=0 
pool1该加入任务了 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
  pool-1-thread-1:25 
  pool-1-thread-2:26 
  pool-1-thread-3:28 
  pool-1-thread-5:27 
  pool-1-thread-4:29 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
  pool-1-thread-1:30 
  pool-1-thread-4:34 
  pool-1-thread-3:32 
  pool-1-thread-5:33 
  pool-1-thread-2:31 
返回此执行程序使用的任务队列=0 
pool1该加入任务了 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
  pool-1-thread-1:35 
  pool-1-thread-4:36 
  pool-1-thread-3:37 
  pool-1-thread-2:39 
  pool-1-thread-5:38 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
  pool-1-thread-1:40 
  pool-1-thread-5:44 
  pool-1-thread-2:43 
  pool-1-thread-3:42 
  pool-1-thread-4:41 
返回此执行程序使用的任务队列=0 
pool1该加入任务了 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10 
  pool-1-thread-1:45 
  pool-1-thread-2:47 
  pool-1-thread-3:48 
  pool-1-thread-5:46 
  pool-1-thread-4:49 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
返回此执行程序使用的任务队列=5 
  pool-1-thread-1:50 
返回此执行程序使用的任务队列=4 
pool1该加入任务了 
返回此执行程序使用的任务队列=14 
  pool-1-thread-5:53 
  pool-1-thread-3:52 
  pool-1-thread-4:54 
  pool-1-thread-2:51 
返回此执行程序使用的任务队列=10 
返回此执行程序使用的任务队列=10
。。。。。
可以看到,库存永远不会超过14。
太忙了,没空详细写,如果你有不同的见解,请留下代码,不要对作者本人进行攻击评论。谢谢各位!
本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/1036186,如需转载请自行联系原作者

Java多线程生产者消费者调度实现相关推荐

  1. Java多线程-生产者消费者问题(多个消费者多个生产者)

    Java多线程-生产者消费者问题(多个消费者多个生产者) public class ConsumerProcuderDemo {public static void main(String[] arg ...

  2. java多线程 生产者消费者_java多线程之-生产者与消费者

    java多线程之-并发协作[生产者与消费者]模型 对于多线程程序来说,不管c/c++ java python 等任何编程语言,生产者与消费者模型都是最为经典的.也就是可以说多线程的并发协作 对于此模型 ...

  3. Java多线程——生产者消费者问题

    创建多个线程去执行不同的任务,如果这些任务之间有着某种关系,那么线程之间必须能够通信来协调完成工作. 生产者消费者问题(英语:Producer-consumer problem)就是典型的多线程同步案 ...

  4. java多线程 生产者消费者_java多线程之生产者消费者经典问题 - 很不错的范例

    /**生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二,既然是生产者.消费者,那么生产者类和消费者类就是必须的 * 第三,生产什么,消费什么,所以物品类是必须的,这里 ...

  5. java多线程-生产者消费者模式

    进程定义: 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位 线程定义: 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能 ...

  6. Java多线程 生产者-消费者问题示例

    奶箱:相当于缓冲区,容量有限,生产者放入牛奶,消费者拿走牛奶 生产者:实现 Runnable 接口,箱子内有牛奶就取出,没有就等着 消费者:实现 Runnable 接口,箱子还有剩余空间就往里放牛奶, ...

  7. Java多线程-生产者与消费者

    Java多线程生产者与消费者,准确说应该是"生产者-消费者-仓储"模型,使用了仓储,使得生产者消费者模型就显得更有说服力. 对于此模型,应该明确一下几点: 1.生产者仅仅在仓储未满 ...

  8. 【Java】生产者消费者模型

    [Java]生产者消费者模型 0x1 前言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,生产者往存储空间中添加产品,消费者从存储空间中取走产品,当存储空间 ...

  9. 多线程生产者消费者模型

    1. 基础知识: 1. 什么是生产者-消费者模式: 比如有两个进程A和B,它们共享一个固定大小的缓冲区,A进程产生数据放入缓冲区,B进程从缓冲区中取出数据进行计算,那么这里其实就是一个生产者和消费者的 ...

最新文章

  1. PHP中可变变量和php可变函数到底有什么用?
  2. python里面的之前打过的记忆信息-python中的if __name__ == 'main'
  3. list vue 删除后页面渲染_浅谈Vue项目实战(页面渲染+事件绑定)
  4. 【Android 应用开发】Paint 图形组合 Xfermod 之 合成模式表示方法 ( Xfermod 使用步骤 | 透明度 颜色值 公式表示方法 | 老版本表示方法 | 合成区域分块 )
  5. arm linux下编译库System.Net.Primitives.dll和System.Xml.XmlSerializer.dll
  6. 燕赵志愿云如何认证_如何成为中国志愿服务网注册志愿者?操作秘籍!
  7. 数字证书 - Java加密与安全
  8. PWA(Progressive Web App)入门系列:(三)PWA关键技术Manifest
  9. 计算机操作系统英文版课后答案,计算机操作系统(第3版)课后习题答案(完整版)...
  10. 拿到一台新的Windows电脑,我会做什么?
  11. CNN反向传播算法过程
  12. JNI调用两层C++动态库
  13. VoiceDial首款语音识别软件使用教程
  14. mysql字符类型总结及常用字符函数
  15. python沙箱逃逸小结
  16. python Django项目汇总(毕设、课设、学习)
  17. c++之 推箱子小游戏
  18. JavaScript 数据结构与算法(队列)
  19. CSS最详细的基础教程
  20. 配置路由协议rip和ospf

热门文章

  1. UA MATH564 概率论I 求离散型随机变量的分布1
  2. Prolog基本程序
  3. Bash命令行历史用法【转】
  4. AES CBC模式下的CBC bit flipping Attack
  5. CSAPP lab2 二进制拆弹 binary bombs phase_6
  6. 洛谷 P1708 天然气井 题解
  7. 经典算法问题 - 最大连续子数列和
  8. UOJ 152 汉诺塔 分治
  9. ios开发--常用的高效开发的宏
  10. 全球隔夜主要金融市场回顾