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