1.背景
连锁零售公司旗下有1000家门店,每个门店的选品过程都是独立的,每个门店选品执行的时间平均为30秒,单线程串行执行所有门店选品需要500分钟,因为业务上下游给的时间有限,需要减少整体的执行时间,执行时间控制在100分钟内。
2.思路
并行执行,500/100=5,同时有五家门店在选品,单台机器并发执行的能力是有限,若超过单台机器的并发能力可以用定时任务分片的方式来扩展并发能力。
3.模拟代码
3.1.门店选品
/**
* 门店选品
*
public class StoreSelection {
/**
* 门店编码
*/
private String storeCode;
private final static String TXT = "门店选品开始门店选品开始门店选品开始门店选品开始门店选品开始门店选品开始门店选品开始门店选品开始门店选品开始";
public StoreSelection(String storeCode) {
this.storeCode = storeCode;
}
public String select(){
System.out.println(String.format("%s门店编码=%s的门店选品开始", LocalDateTime.now(), storeCode));
Base64.Encoder encoder = Base64.getEncoder();
LocalDateTime start = LocalDateTime.now();
LocalDateTime end = start.plusSeconds(30);
//模拟选品过程中有异常
if ("A10".equals(storeCode)) {
throw new RuntimeException(storeCode + "门店选品异常请处理");
}
while (LocalDateTime.now().isBefore(end)) {
//加重CPU负载
encoder.encode(TXT.getBytes());
//System.out.println(String.format("%s门店编码=%s的门店选品执行中", LocalDateTime.now(), storeCode));
}
System.out.println(String.format("%s门店编码=%s的门店选品完成", LocalDateTime.now(), storeCode));
return storeCode + "门店选品完成";
}
public static void main( String[] args ) {
new StoreSelection("A1").select();
}
}
3.2.连锁零售公司旗下所有门店选品
public class GroupSelection{
public static void main( String[] args ) {
List<String> storeCodeList = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
storeCodeList.add("A"+i);
}
System.out.println("门店组选品开始");
ExecutorService executor = Executors.newFixedThreadPool(5);
List<Future<String>> futureList = storeCodeList.stream()
.map(storeCode -> executor.submit(() -> new StoreSelection(storeCode).select()))
.collect(Collectors.toList());
while(!futureList.stream().allMatch(Future::isDone)){
System.out.println("等待所有门店选品执行结束");
}
String re = futureList.stream().map(future -> {
try {
return future.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
return e.getMessage();
}
}).collect(Collectors.joining(","));
System.out.println(re);
System.out.println("门店组选品完成");
executor.shutdown();
}
}
网友评论