并发编程(四)_Master-Worker代码

Master-Worker模式的实例代码:
【Master.class】

package com.jxb.thread11;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * Master-Worker模式——并行计算模式
 *  Master 负责接收和分配任务
 */
public class Master {
    
    //1、应该有一个 承装所有任务的容器
    private ConcurrentLinkedQueue<Task> workQueue=new ConcurrentLinkedQueue<Task>();
    
    //2、使用HashMap去承装所有的worker对象
    private HashMap<String, Thread> workers=new HashMap<String, Thread>();
    
    //3、使用一个容器承装每一个worker并行执行的任务的结果集
    private ConcurrentHashMap<String, Object> resultMap=new ConcurrentHashMap<String, Object>();
    
    /**
     * 4、构造函数
     * @param worker        worker对象
     * @param worlerCount   多少个worker对象(子节点)
     */
    public Master(Worker worker,int worlerCount){
        // 每一个worker对象都需要有master的引用,workQueue由于任务的领取
        worker.setWorkerQueue(this.workQueue);
        // resultMap 用于任务的提交
        worker.setResultMap(this.resultMap);
        
        //循环将worker装入workers容器
        for(int i=0;i<worlerCount;i++){
            //key表示每一个worker的名字(方便跟踪),value表示线程执行对象(worker对象,实现线程)
            workers.put("子节点"+Integer.toString(i), new Thread(worker));
        }
    }
    
    //5、提交方法(往任务队列里面装任务)
    public void submit(Task task){
        this.workQueue.add(task);
    }
    
    //6、执行方法(启动应用程序,让所有的worker工作)
    public void execute(){
        //循环Map的方式(启动workers容器 的 所有线程),让worker开始工作
        for(Map.Entry<String, Thread> me:workers.entrySet()){
            me.getValue().start();
        }
    }
    
    //7、判断任务是否执行完毕(线程是否都停止)
    public boolean isComplete() {
        for(Map.Entry<String, Thread> me:workers.entrySet()){
            //判断线程的状态,是否是停止(Thread.State.TERMINATED)
            if(me.getValue().getState()!=Thread.State.TERMINATED){
                return false;   //只要有一个线程的状态不是停止,就返回false
            }
        }
        return true;
    }

    //8、返回结果集
    public int getResult() {
        int ret=0;
        for (Map.Entry<String, Object> result : resultMap.entrySet()) {
            //汇总结果集的逻辑(不一定是++)
            ret+=(Integer)result.getValue();
        }
        return ret;
    }
}

【Worker.class】

package com.jxb.thread11;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 *Master-Worker模式——并行计算模式
 *  Worker 负责处理子任务
 */
public class Worker implements Runnable {

    //接收引用
    private ConcurrentLinkedQueue<Task> workQueue;
    private ConcurrentHashMap<String, Object> resultMap;
    
    /**
     * 引用 Master里面的workerQueue,方便领取任务(领取一个少一个)
     * @param workQueue
     */
    public void setWorkerQueue(ConcurrentLinkedQueue<Task> workQueue) {
        this.workQueue=workQueue;   
    }

    /**
     * 引用 Master里面的resultMap,方便将每个worker里卖弄处理的结果,返回给Master的结果集容器里面
     * @param resultMap
     */
    public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
        this.resultMap=resultMap;
    }
    
    /**
     * 处理一个一个的任务
     */
    @Override
    public void run() {
        while(true){
            Task input=this.workQueue.poll(); //从队列中取出任务并移除
            if(input==null){    //当没有任务时,退出循环
                break;
            }
            /**
             * 真正的去做业务处理
             */
            //Object output=handler(input);
            Object output=MyWorker.handler(input); //优化后的代码01
            //将任务的返回结果 放入结果集容器里面(任务编号/任务名称,任务处理的结果)
            this.resultMap.put(Integer.toString(input.getId()), output);
        }
    }

//------------------------------------代码优化01(将具体的任务实现封装出去)MyWorker,去重写-------------------------------------
    /**
     * 具体的任务
     * @param input 任务
     * @return  返回处理的结果
     */
    /*private Object handler(Task input) {
        Object output=null;
        try {
            //表示处理task任务的耗时,可能是数据的加工也可能是操作数据库
            Thread.sleep(500);
            output=input.getPrivce();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return output;
    }*/

    public static Object handler(Task input){
        return null;
    }

}

【Main.class】

package com.jxb.thread11;

import java.util.Random;

/**
 * Master-Worker 模式的测试类
 */
public class Main {
    public static void main(String[] args) {
        /**
         * (实例化一个worker,需要几个子任务(进程))
         */
        //Master master=new Master(new Worker(), 10);
        //Master master=new Master(new MyWorker(), 10); //代码优化01
        System.out.println("当前机器可用的线程数:"+Runtime.getRuntime().availableProcessors());
        //线程数不能随便加,应该根据自己的电脑性能来
        Master master=new Master(new MyWorker(), Runtime.getRuntime().availableProcessors());   //代码优化02
        
        // 100个任务
        Random random=new Random();
        for (int i = 1; i <= 100; i++) {
            Task task=new Task();
            task.setId(i);
            task.setName("任务"+i);
            task.setPrivce(random.nextInt(1000));
            master.submit(task); //提交任务
        }   
        
        master.execute();   //启动任务
        
        long start=System.currentTimeMillis();
        
        //判断所有任务是否执行完成(所有的线程都执行完成了)
        while(true){
            if(master.isComplete()){
                long end=System.currentTimeMillis()-start;
                int ret= master.getResult();
                System.out.println("汇总结果集最后的值:"+ret+" ,执行耗时"+end);
                break;
            }
        }
    }
}

【Task.class】

package com.jxb.thread11;
/**
 * 任务
 */
public class Task {
    private int id;         //编号
    private String name;    //任务名称
    private int privce;     //价格
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getPrivce() {
        return privce;
    }
    public void setPrivce(int privce) {
        this.privce = privce;
    }
}

【MyWorker.class】

package com.jxb.thread11;
/**
 * 具体需要完成的任务类,可以多个
 */
public class MyWorker extends Worker{
    /**
     * 重写handler()——具体的任务
     * @param input 任务
     * @return  返回处理的结果
     */
    public static Object handler(Task input) {
        Object output=null;
        try {
            //表示处理task任务的耗时,可能是数据的加工也可能是操作数据库
            Thread.sleep(500);
            output=input.getPrivce();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return output;
    }
}

【效果截图】


运行效果.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,795评论 25 707
  • 找到自己想要的资源 在互联网快速发展的今天,网络上的资源无所不包,可是你能快速就能找到自己需要的资源吗?估计能做到...
    多做减法阅读 133评论 0 0
  • 我们总是忙忙碌碌,总是被各种琐事缠绕着,总以为生活只有眼前的苟且,岂不知,诗和远方竟近在咫尺 盛夏的早晨因为前几天...
    tuzhu002阅读 614评论 1 5
  • 今天跟大家分享我们的工具,我就是微商的八大兵器! 现在回想一开始老师要求我们看电影《走出亚马逊》实...
    盈盈1230阅读 213评论 0 0