关于JAVA并发执行,主要是借助多线程和JAVA并发包,分两种情况,一个是有返回值,一个是没有返回值。有返回值是需要并发执行完以后拿到结果做下一步的操作,没有返回值主要是并行执行一些独立的任务。个人理解决定使用到并发技术的因素是:多个不相关的没有相互依赖的任务(代码段),在串行的执行下太耗时了,需要提升性能而采取的措施。下面举一个近期项目中使用的并发技术的场景。
前端页面需要显示互不相关的一些统计信息的图形化功能,比如大屏上的几个图表,可以发起一次请求服务器端并发执行,将结果汇总一次性返回,也可以浏览器分多次请求。因此是否需要并发技术,还是需要综合考虑哪一种更适合自己,不是为了用而用。由于该需求需要汇总数据,因此需要使用到有返回值的并发执行技术。
public class ObjectStatusCallable implements Callable<Map<String,Object>> {
private ObjectService objectServiceImpl;
private Integer id;
public ObjectStatusCallable(ObjectService objectServiceImpl, Integer id){
this.objectServiceImpl = objectServiceImpl;
this.id = id;
}
@Override
public Map<String,Object> call() {
List<Object> objectList = new ArrayList();
Map<String,Object> resultMap = new HashMap<>();
resultMap.put("objectName",objectList);
return resultMap;
}
}
@Override
public Map<String, Object> getStatisticList(Integer id) {
long start = System.currentTimeMillis();
Map<String,Object> map = new HashMap<>();
ExecutorService executors = Executors.newFixedThreadPool(3);
List<Future<Map<String,Object>>> futures = new ArrayList<>();
Future<Map<String,Object>> objectFuture = executors.submit(new ObjectStatusCallable(objectServiceImpl, id));
futures.add(noteBookFuture);
......
List<ObjectPO> mapObj = null;
......
try {
for (Future<Map<String, Object>> future : futures) {
Map<String, Object> resultMap = future.get();
if(resultMap.containsKey("objectName")){
mapObj = (List<ObjectPO>) resultMap.get("objectName");
}
......
}
}catch (Exception e){
e.printStackTrace();
}
executors.shutdown();
long end = System.currentTimeMillis();
System.out.println("end-start:"+(end-start));
map.put("objectName",mapObj);
......
return map;
}
上面代码包含了部分的伪代码,比如省略号的地方,涉及到很多业务的代码,这里面包含很多的数据库层面的数据查询。getStatisticList是业务层Service中的方法,objectServiceImpl通过Autowire的方式注入。在此只是提供了并发包Callable和ExecutorService的使用。可以根据实际需求传入业务参数和封装统一的返回结果