Master-Worker模式

216 阅读2分钟

Master-Worker模式是一种常见的高并发模式,它的核心思想是任务的调度和执行分离,调度 任务的角色为Master,执行任务的角色为Worker,Master负责接收和、分配任务和合并(Merge) 任务结果,Worker负责执行任务。Master-Worker模式是一种归并类型的模式。

image.png

package com.wan.mode.masterworker;

![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/02658f6ba61c47f69734ac01c521eb2d~tplv-k3u1fbpfcp-watermark.image?)
import com.sun.corba.se.spi.orbutil.threadpool.Work;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author wan
 * @Description:
 * @date 2023/5/10 9:59
 */
public class Master<T extends Task, R> {
    //所有worker集合
    private HashMap<String, Worker<T, R>> workers = new HashMap<>();
    //任务集合
    private LinkedBlockingQueue<T> taskQueue = new LinkedBlockingQueue<>();
    //任务处理结果集合
    protected Map<String, R> resultMap = new ConcurrentHashMap<>();
    //Master任务调度线程
    private Thread thread = null;
    //保持最终的和
    private AtomicLong sum = new AtomicLong(10);

    public Master(int workerCount) {
        //每个workder都需要持有 taskQueue得引用
        for (int i = 0; i < workerCount; i++) {
            Worker<T,R> worker = new Worker<>();
            workers.put("子节点" +i, worker);
            thread = new Thread(() -> this.excute());
            thread.start();
        }
    }

    //提交任务放到队列中
    public void submit(T task) {
        taskQueue.add(task);
    }

    // 获取worker 结果处理的回调函数
    private void resultCallBack(Object o) {
        Task<R> task = (Task<R>)o;
        String taskName = "Worker:" + task.getWorkerId() + "-" + "Task:" + task.getId();
        R result = task.getResult();
        resultMap.put(taskName, result);
        sum.getAndAdd((Integer) result);
    }

    //启动所有子任务
    public void excute() {
        for(;;) {
            for (Map.Entry<String, Worker<T, R>> stringWorkerEntry : workers.entrySet()) {
                T task = null;
                try {
                    //获取队列中的任务
                    task = this.taskQueue.take();
                    Worker worker = stringWorkerEntry.getValue();
                    worker.submit(task, this::resultCallBack);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }


    public void printResult() {
        System.out.println("---------------sum is: " + sum.get());
        for (Map.Entry<String, R> stringREntry : resultMap.entrySet()) {
            String taskName = stringREntry.getKey();
            System.out.println(taskName + ": " + stringREntry.getValue());
        }
    }
}
package com.wan.mode.masterworker;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import org.apache.jute.Index;

/**
 * @author wan
 * @Description:
 * @date 2023/5/10 10:01
 */
public class Worker<T extends Task, R> {
    //接收任务的阻塞队列
    private LinkedBlockingQueue<T> taskQueue = new LinkedBlockingQueue<>();
    //worker 的编号
    static AtomicInteger index = new AtomicInteger(1);
    private int workerId;
    //执行任务的线程
    private Thread thread = null;

    public Worker() {
        this.workerId = index.getAndIncrement();
        thread = new Thread(() -> this.run());
        thread.start();
    }

    public void run() {
        for (; ; ) {
            try {
                //从阻塞队列中提取任务
                T task = this.taskQueue.take();
                task.setWorkerId(workerId);
                task.execute();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //接收任务到异步队列
    public void submit(T task, Consumer<R> action) {
        task.resultAction = action; //设置任务的回调方法
        try {
            this.taskQueue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
package com.wan.mode.masterworker;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import lombok.Data;

/**
 * @author wan
 * @Description:
 * @date 2023/5/10 10:01
 */
@Data
public class Task<R> {
    static AtomicInteger index = new AtomicInteger(1);
    //任务的回调函数
    public Consumer<Task<R>> resultAction;
    //任务的id
    private int id;
    // worker ID
    private int workerId;
    //计算结果
    R result = null;

    public Task() {
        this.id = index.getAndIncrement();
    }

    public void execute() {
        this.result = this.doExecute();
//执行回调函数
        resultAction.accept(this);
    }

    //由子类实现
    protected R doExecute() {
        return null;
    }
}
package com.wan.mode.masterworker;

import java.util.concurrent.TimeUnit;

/**
 * @author wan
 * @Description:
 * @date 2023/5/10 10:48
 */
public class MasterWorkerTest {
    //简单任务
    static class SimpleTask extends Task<Integer> {
        @Override
        protected Integer doExecute() {
            System.out.println("task " + getId() + " is done ");
            return getId();
        }
    }

    public static void main(String[] args) {
        //创建Master,包含4个Worker,并启动Master的执行线程
        Master<SimpleTask, Integer> master = new Master<>(4);
        //定期向Master提交任务
       // ThreadUtil.scheduleAtFixedRate(() -> master.submit(new SimpleTask()),
        //        2, TimeUnit.SECONDS);
        //定期从Master提取结果
      //  ThreadUtil.scheduleAtFixedRate(() -> master.printResult(), 5, TimeUnit.SECONDS);
    }
}

Reactor模式就是基于Master-Worker模式实现的