定义:将一个任务(原始任务)分解为若干个语义等同的子任务,并由专门的工作者线程来并行执行子任务

Master: 负责原始任务的分解、子任务的派发和子任务处理结果的合并
service: Master参与者对外暴露的接口,用于接收原始任务,并返回其处理结果
splitWork: 将原始任务分解成若干个语义等同的子任务
callSlaves: 将各个子任务派发给各个Slave实例进行处理
combineResults: 将各个子任务的处理结果进行整合,形成原始任务的处理结果
Salve: 负责子任务的处理
subService: 异步方法,负责执行子任务的处理逻辑
下列代码通过工作者线程将任务分解多个小任务,采用简单轮询进行负载均衡。通过调用dispatchTask()方法执行。
package com.bruce.masterSlave;
import com.bruce.twoPhaseTermination.AbstractTerminatableThread;
import java.io.*;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
/**
* @Author: Bruce
* @Date: 2019/6/1 19:34
* @Version 1.0
*/
public class TPSStat {
public static void main(String[] args) throws Exception {
String logBaseDir = args[0];
String excludedOperationNames = "";
String includedOperationNames = "sendSms,";
String destinationSysName = "*";
int argc = args.length;
if (argc > 2) {
excludedOperationNames = args[1];
}
if (argc > 3) {
excludedOperationNames = args[2];
}
if (argc > 4) {
destinationSysName = args[3];
}
Master processor = new Master(logBaseDir, excludedOperationNames, includedOperationNames, destinationSysName);
}
private static class Master {
final String logFileBaseDir;
final String excludedOperationNames;
final String includedOperationNames;
final String destinationSysNames;
static final int NUMBER_OF_FILES_FOR_EACH_DISPATCH = 5;
static final int WORKER_COUNT = Runtime.getRuntime().availableProcessors();
public Master(String logFileBaseDir, String excludedOperationNames, String includedOperationNames, String destinationSysNames) {
this.logFileBaseDir = logFileBaseDir;
this.excludedOperationNames = excludedOperationNames;
this.includedOperationNames = includedOperationNames;
this.destinationSysNames = destinationSysNames;
}
public ConcurrentMap<String, AtomicInteger> calculate(BufferedReader fileNamesReader) throws IOException {
ConcurrentMap<String, AtomicInteger> repository = new ConcurrentSkipListMap<>();
TPSStat.Worker[] workers = createAndStartWorkers(repository);
dispatchTask(fileNamesReader, workers);
for (int i = 0; i < WORKER_COUNT; i++) {
workers[i].terminate(true);
}
return repository;
}
private TPSStat.Worker[] createAndStartWorkers(ConcurrentMap