【多线程系列二】-master-woker模式:统计单次频率
来源:互联网 发布:客户端软件开发 编辑:程序博客网 时间:2024/05/07 08:14
序:
Master-Worker模式是常用的并行设计模式。核心思想是,系统由两个角色组成,Master和Worker,Master负责接收和分配任务,Worker负责处理子任务。任务处理过程中,Master还负责监督任务进展和Worker的健康状态;Master将接收Client提交的任务,并将任务的进展汇总反馈给Client。各角色关系如下图
但是书上给出的demo比较麻烦。
我按照一个更简洁的方式:模拟统计单词词频的方式。
具体细节如上图,Master对任务进行切分,并放入任务队列;然后,触发Worker处理任务。实际操作中,任务的分配有多种形式,如Master主动拉起Workder进程池或线程池,并将任务分配给Worker;或者由Worker主动领取任务,这样的Worker一般是常驻进程;还有一种解耦的方式,即Master指做任务的接收、切分和结果统计,指定Worker的数量和性能指标,但不参与Worker的实际管理,而是交由第三方调度监控和调度Worker。
demo:如下:
public class Master {// 任务队列static BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(1024);// 子任务处理结果集static Map<String, Integer> resultMap = new ConcurrentHashMap<String, Integer>();public static void main(String[] args) {for (int i = 0; i < 50; i++) {try {String tmp ="AAA";if(i%2==0){tmp ="BBB";}blockingQueue.put("hello world" + i+" "+tmp);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}ExecutorService exector = Executors.newFixedThreadPool(20);ArrayList<Future<Map<String, Integer>>> futures = new ArrayList<Future<Map<String, Integer>>>();for (int j = 0; j < 20; j++) {Future<Map<String, Integer>> futurej = exector.submit(new Task("" + j, blockingQueue));futures.add(futurej);}System.out.println("获取结果中...");for (Future<Map<String, Integer>> f : futures) {try {// if(f.isDone())Map<String, Integer> reMap = f.get();for (Entry<String, Integer> entry : reMap.entrySet()) {resultMap.put(entry.getKey(), resultMap.getOrDefault(entry.getKey(), 0) + entry.getValue());}} catch (Exception e) {e.printStackTrace();}}System.out.println("得到结果.");for (Entry<String, Integer> entry : resultMap.entrySet()) {System.out.print(entry.getKey() + ":" + entry.getValue()+" ");}// 关闭线程池。exector.shutdown();}}class Task implements Callable<Map<String, Integer>> {private String name;private BlockingQueue<String> blockingQueue;public Task(String name, BlockingQueue<String> blockingQueue) {this.name = name;this.blockingQueue = blockingQueue;}@Overridepublic Map<String, Integer> call() {System.out.println(System.currentTimeMillis() + " " + name + "run");Map<String, Integer> wordCount = new HashMap<>();while (true) {try {String input = blockingQueue.poll(1, TimeUnit.SECONDS);if (null != input && StringUtils.isNotBlank(String.valueOf(input))) {String[] words = StringUtils.split(String.valueOf(input), " "); // 分词for (String w : words) {if (StringUtils.isBlank(w)) {continue;}wordCount.put(w, wordCount.getOrDefault(w, 0) + 1);}}else{break;}} catch (InterruptedException e) {break;}}System.out.println(LocalTime.now() + " " + name + "runover");return wordCount;}}因为使用了future跟线程池,大幅简化了代码。可以对比下相关的代码:网上好多就是照搬了葛一鸣原书上代码没改。
执行结果如下:
获取结果中...
20:24:19.991 worker6run
20:24:19.992 worker19run
20:24:19.993 worker3run
20:24:19.995 worker2run
20:24:19.996 worker18run
20:24:20 worker10run
20:24:20 worker5run
20:24:20.001 worker14run
20:24:20.001 worker11run
20:24:20.002 worker4run
20:24:20.002 worker1run
20:24:20.002 worker13run
20:24:20.002 worker15run
20:24:20.003 worker7run
20:24:20.002 worker8run
20:24:20.003 worker12run
20:24:20.003 worker0run
20:24:20.003 worker9run
20:24:20.003 worker17run
20:24:20.003 worker16run
20:24:21.010 worker3runover
20:24:21.011 worker18runover
20:24:21.011 worker2runover
20:24:21.011 worker6runover
20:24:21.011 worker14runover
20:24:21.012 worker8runover
20:24:21.012 worker16runover
20:24:21.012 worker12runover
20:24:21.012 worker7runover
20:24:21.012 worker11runover
20:24:21.012 worker4runover
20:24:21.011 worker0runover
20:24:21.011 worker15runover
20:24:21.011 worker19runover
20:24:21.013 worker10runover
20:24:21.013 worker5runover
20:24:21.014 worker1runover
20:24:21.014 worker17runover
20:24:21.017 worker13runover
20:24:21.017 worker9runover
得到结果.
world4:1
world5:1
world2:1
BBB:25
world3:1
world8:1
world9:1
world6:1
world30:1
world7:1
world39:1
world31:1
world32:1
world33:1
world34:1
world35:1
world36:1
world37:1
world38:1
AAA:25
world28:1
world29:1
world20:1
world21:1
world22:1
hello:50
world23:1
world24:1
world0:1
world25:1
world1:1
world26:1
world27:1
world17:1
world18:1
world19:1
world10:1
world11:1
world12:1
world13:1
world14:1
world15:1
world16:1
world40:1
world41:1
world42:1
world43:1
world44:1
world45:1
world46:1
world47:1
world48:1
world49:1
当然,这里只是介绍这种思路,典型的还是要考虑master异常怎么办,任务线程的处理结果如何处理,存表还是发消息。还有线程安全问题。多个节点如何做分布式的。
参考:
http://blog.csdn.net/wendingzhulu/article/details/52708472
阅读全文
0 0
- 【多线程系列二】-master-woker模式:统计单次频率
- 多线程安全(二)之单例模式
- 单例模式与多线程(二)
- java 多线程 master worker模式
- JavaScript设计模式系列二:单例模式
- mysql模式:master/slave(二)
- 多线程模式之Master-Worker模式
- 多线程设计模式-- Master-Worker模式
- Master-Worker模式 多线程设计模式
- 多线程单例模式
- 并发模式(二)Master-Worker模式
- 通过多线程模拟实现Master-Worker模式
- 多线程之Master-Worker工作模式学习
- 多线程设计模式(Future/Master-Worker)
- 多线程——worker-master模式
- 多线程编程中的Master-Worker模式
- Java 多线程设计模式Master-Slave
- 单例模式-多线程单例模式
- 从键盘输入一个大写字母,转换成小写字母
- 专访姚冬:All-in-One,智能时代下企业需要更快速的变革
- Swift_复数类
- 详解SQL盲注测试高级技巧
- 关于js根据类名获取元素
- 【多线程系列二】-master-woker模式:统计单次频率
- 很好用的下拉刷新上拉加载的框架smartrefreshlayout属性
- 牛客网错题集锦3
- springcloud(暂时结束)
- 12种不宜使用的Javascript语法---《Javascript语言精粹》
- 自动轮播加Scrollview加tablyout加多条目
- (算法)初级排序算法
- 购物车
- CS 300 Tree Antichain 构造,树,二分染色