目录
看题:
要求:
解题:
先创建 三个 实体类。
ok, 此时需要对字段处理 效验,并有相应提示。
ok,接下来使用多线程批量处理。
ok,测试
输出结果
老司机开车,飙车有炫酷。多么迷人的idea。放张图镇镇场面。

看题:
备注:学生类 与 地址类 为一对一,学生类 与 电子产品类 为一对多。
要求:
多线程批量校验100多名学生信息,但是校验的方法每次只能同时校验5名学生。要求这一百多名学生信息的校验结果同时返回到校验结果展示页面。校验结果展示模板为:XXX字段不能为空!(校验一个类时,只要遇到必填校验不通过,就可返回,不必继续校验完剩余字段)
写的时候,尽量把校验方法写成适用于各种类的通用方法。不要硬编码。
解题:
先创建 三个 实体类。
Address
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 地址类
*
* @author wbw
* @date 2019/7/19 9:29
*/
@Data
@Accessors(chain = true)
public class Address implements Serializable {
/**
* 地区
*/
private String provence;
/**
* 城市
*/
private String city;
/**
* 下级
*/
private String down;
}
Electronic
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 电子产品类
*
* @author wbw
* @date 2019/7/19 9:28
*/
@Data
@Accessors(chain = true)
public class Electronic implements Serializable {
private Integer id;
private String name;
private String color;
}
Student
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* 学生类
*
* @author wbw
* @date 2019/7/19 9:25
*/
@Data
@Accessors(chain = true)
public class Student implements Serializable {
/**
* id
*/
private Long cardId;
/**
* 名称
*/
private String name;
/**
* 性别
*/
private String sex;
/**
* 电子产品类
*/
private List<Electronic> electronics;
/**
* 地址
*/
private Address address;
}
所需要的 pom
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
ok, 此时需要对字段处理 效验,并有相应提示。
考虑可以使用 map 前面为字段名称,后面为字段的值。我这里用了json。
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.jayway.jsonpath.JsonPath;
import lombok.Getter;
import java.util.stream.Stream;
/**
* 通用效验
*
* @author wbw
* @date 2019/7/19 12:42
*/
@Getter
class ValidCommon {
private String msg;
private static final String TEMPLATE_2 = "字段 %s.%s 效验通过....";
private static final String TEMPLATE_1 = "字段 %s.%s 效验未通过....";
/**
* 是否为真
*
* @param obj 参数
* @author wbw
* @date 12:46 2019/7/19
*/
private boolean toValidFlag(Object... obj) {
if (ObjectUtil.isEmpty(obj)) {
return true;
}
for (Object o : obj) {
if (ObjectUtil.isEmpty(o)) {
return true;
}
}
return false;
}
/**
* 检查字段的值是否有效
*
* @param field 检查的字段
* @param clazz 对象
* @return boolean
* @author wbw
* @date 14:03 2019/7/19
*/
boolean checkField(Object clazz, Object... field) {
if (toValidFlag(field)) {
return true;
}
String json = JSONUtil.parse(clazz).toJSONString(2);
String className = clazz.getClass().getSimpleName();
return Stream.of(field).anyMatch((x) -> {
if (toValidFlag(x)) {
msg = String.format(TEMPLATE_1, className, x);
return true;
}
try {
if (toValidFlag(JsonPath.parse(json).read("$." + x).toString())) {
msg = String.format(TEMPLATE_1, className, x);
return true;
}
} catch (Exception e) {
msg = String.format(TEMPLATE_1, className, x);
return true;
}
msg = String.format(TEMPLATE_2, className, x);
return false;
});
}
}
所需要的pom
<dependency> <groupId>com.jayway.jsonpath</groupId> <artifactId>json-path</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.5.16</version> </dependency>
ok,接下来使用多线程批量处理。
这里使用了 ExecutorService 线程池,注意,在执行完毕的时候,子线程和主线程是异步的,所以要等待子线程执行完毕,切记。
pool.awaitTermination(awaitMaxTimeMs, TimeUnit.MILLISECONDS)
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.hb.myproject.thread.entity.Address;
import com.hb.myproject.thread.entity.Electronic;
import com.hb.myproject.thread.entity.Student;
import lombok.extern.log4j.Log4j2;
import java.util.*;
import java.util.concurrent.*;
/**
* 批量处理
*
* @author wbw
* @date 2019/7/19 9:36
*/
@Log4j2
public class BatchProcessing {
private ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
.setNameFormat(BatchProcessing.class.getName() + "-pool-%d").build();
private ExecutorService pool = new ThreadPoolExecutor(5, 5,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
/**
* 批量处理
*
* @param student 多个学生信息
* @return key 为id信息,value 为输出结果
* @author wbw
* @date 9:50 2019/7/19
*/
public Map<Student, String> desiredResult(List<Student> student) {
if (student == null || student.size() < 1) {
log.info("无数据处理....");
return new HashMap<>(0);
}
final Map<Student, String> map = new ConcurrentHashMap<>(student.size());
student.forEach(stu -> pool.execute(() -> verifyStu(stu, map)));
this.shutdown();
return map;
}
/**
* 执行线程完成
*
* @author wbw
* @date 15:46 2019/7/19
*/
public void shutdown() {
pool.shutdown();
try {
int awaitMaxTimeMs = 3000;
if (!pool.awaitTermination(awaitMaxTimeMs, TimeUnit.MILLISECONDS)) {
// 超时的时候向线程池中所有的线程发出中断(interrupted)。
pool.shutdownNow();
}
} catch (InterruptedException e) {
log.error(e);
}
}
/**
* 验证
*
* @param stu 处理信息
* @param map 结果存储
* @return boolean
* @author wbw
* @date 10:29 2019/7/19
*/
private void verifyStu(Student stu, Map<Student, String> map) {
ValidCommon valid = new ValidCommon();
if (valid.checkField(stu, "cardId", "name", "electronics", "address")) {
map.put(stu, valid.getMsg());
return;
}
List<Electronic> electronics = stu.getElectronics();
for (Electronic electronic : electronics) {
if (valid.checkField(electronic, "id", "name")) {
map.put(stu, valid.getMsg());
return;
}
}
Address address = stu.getAddress();
if (valid.checkField(address, "city", "down")) {
map.put(stu, valid.getMsg());
return;
}
map.put(stu, valid.getMsg());
}
}
所需要的pom
<!-- https://mvnrepository.com/artifact/com.google.guava/guava --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>27.0.1-jre</version> </dependency>
ok,测试
import cn.hutool.json.JSONUtil;
import com.hb.myproject.thread.entity.Address;
import com.hb.myproject.thread.entity.Electronic;
import com.hb.myproject.thread.entity.Student;
import com.hb.myproject.thread.local.BatchProcessing;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* @author wbw
* @date 2019/7/19 13:44
*/
public class Test {
public static void main(String[] args) {
BatchProcessing batchProcessing = new BatchProcessing();
List<Student> students = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
Student student = new Student();
Address address = new Address();
if (i % 3 == 2) {
address.setCity("xxxaxa" + i).setProvence("gw33wg" + i).setDown("fewgfew" + i);
}
student.setAddress(address).setCardId(i + 45L).setName("xxxx" + i);
List<Electronic> electronics = new LinkedList<>();
for (int j = 0; j < 10; j++) {
Electronic electronic = new Electronic();
electronic.setColor("red" + j).setId(j).setName("xxaxsqf" + j);
electronics.add(electronic);
}
student.setElectronics(electronics);
students.add(student);
}
Map<Student, String> studentStringMap = batchProcessing.desiredResult(students);
System.out.println(studentStringMap.size());
System.out.println(JSONUtil.parse(studentStringMap).toJSONString(2));
}
}