在工作中,会出现大量需要循环操作的问题。有时候会碰到需要加快查询时间,提高响应效率的场景。解决此类的问题核心不使用同步的方法,采用多线程的思路去解决。以下是解决的几种思路
采用Java8使用并行流(ParallelStream)
如下的demo类,走同步循环的话需要100s左右,使用并行流可提高效率
@GetMapping ("/testSync1")
public String testSync1() throws InterruptedException {
Date begin = new Date();
List<Integer> integerList = new ArrayList<>();
for (int i = 0;i<100;i++){
integerList.add(i);
}
List<User> resultList = integerList.parallelStream().map(e->{
User user = new User();
try {
Thread.sleep(1000);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
user.setId(e);
user.setName(e+"条");
return user;
}).collect(Collectors.toList());
Date end = new Date();
long interval = (end.getTime() - begin.getTime())/1000;
System.out.println("耗费时间:"+interval+"s");
System.out.println(resultList.toString());
return resultList.toString();
}
打印结果如下所示
耗费时间:7s
[User{name='0条', id=0, sex='null'}, User{name='1条', id=1, sex='null'}, User{name='2条', id=2, sex='null'}, User{name='3条', id=3, sex='null'}, User{name='4条', id=4, sex='null'}, User{name='5条', id=5, sex='null'}, User{name='6条', id=6, sex='null'}, User{name='7条', id=7, sex='null'}, User{name='8条', id=8, sex='null'}, User{name='9条', id=9, sex='null'}, User{name='10条', id=10, sex='null'}, User{name='11条', id=11, sex='null'}, User{name='12条', id=12, sex='null'}, User{name='13条', id=13, sex='null'}, User{name='14条', id=14, sex='null'}, User{name='15条', id=15, sex='null'}, User{name='16条', id=16, sex='null'}, User{name='17条', id=17, sex='null'}, User{name='18条', id=18, sex='null'}, User{name='19条', id=19, sex='null'}, User{name='20条', id=20, sex='null'}, User{name='21条', id=21, sex='null'}, User{name='22条', id=22, sex='null'}, User{name='23条', id=23, sex='null'}, User{name='24条', id=24, sex='null'}, User{name='25条', id=25, sex='null'}, User{name='26条', id=26, sex='null'}, User{name='27条', id=27, sex='null'}, User{name='28条', id=28, sex='null'}, User{name='29条', id=29, sex='null'}, User{name='30条', id=30, sex='null'}, User{name='31条', id=31, sex='null'}, User{name='32条', id=32, sex='null'}, User{name='33条', id=33, sex='null'}, User{name='34条', id=34, sex='null'}, User{name='35条', id=35, sex='null'}, User{name='36条', id=36, sex='null'}, User{name='37条', id=37, sex='null'}, User{name='38条', id=38, sex='null'}, User{name='39条', id=39, sex='null'}, User{name='40条', id=40, sex='null'}, User{name='41条', id=41, sex='null'}, User{name='42条', id=42, sex='null'}, User{name='43条', id=43, sex='null'}, User{name='44条', id=44, sex='null'}, User{name='45条', id=45, sex='null'}, User{name='46条', id=46, sex='null'}, User{name='47条', id=47, sex='null'}, User{name='48条', id=48, sex='null'}, User{name='49条', id=49, sex='null'}, User{name='50条', id=50, sex='null'}, User{name='51条', id=51, sex='null'}, User{name='52条', id=52, sex='null'}, User{name='53条', id=53, sex='null'}, User{name='54条', id=54, sex='null'}, User{name='55条', id=55, sex='null'}, User{name='56条', id=56, sex='null'}, User{name='57条', id=57, sex='null'}, User{name='58条', id=58, sex='null'}, User{name='59条', id=59, sex='null'}, User{name='60条', id=60, sex='null'}, User{name='61条', id=61, sex='null'}, User{name='62条', id=62, sex='null'}, User{name='63条', id=63, sex='null'}, User{name='64条', id=64, sex='null'}, User{name='65条', id=65, sex='null'}, User{name='66条', id=66, sex='null'}, User{name='67条', id=67, sex='null'}, User{name='68条', id=68, sex='null'}, User{name='69条', id=69, sex='null'}, User{name='70条', id=70, sex='null'}, User{name='71条', id=71, sex='null'}, User{name='72条', id=72, sex='null'}, User{name='73条', id=73, sex='null'}, User{name='74条', id=74, sex='null'}, User{name='75条', id=75, sex='null'}, User{name='76条', id=76, sex='null'}, User{name='77条', id=77, sex='null'}, User{name='78条', id=78, sex='null'}, User{name='79条', id=79, sex='null'}, User{name='80条', id=80, sex='null'}, User{name='81条', id=81, sex='null'}, User{name='82条', id=82, sex='null'}, User{name='83条', id=83, sex='null'}, User{name='84条', id=84, sex='null'}, User{name='85条', id=85, sex='null'}, User{name='86条', id=86, sex='null'}, User{name='87条', id=87, sex='null'}, User{name='88条', id=88, sex='null'}, User{name='89条', id=89, sex='null'}, User{name='90条', id=90, sex='null'}, User{name='91条', id=91, sex='null'}, User{name='92条', id=92, sex='null'}, User{name='93条', id=93, sex='null'}, User{name='94条', id=94, sex='null'}, User{name='95条', id=95, sex='null'}, User{name='96条', id=96, sex='null'}, User{name='97条', id=97, sex='null'}, User{name='98条', id=98, sex='null'}, User{name='99条', id=99, sex='null'}]
采用CompletableFuture实现带有返回值
主方法如下
@GetMapping ("/testSync")
public String testSync() throws InterruptedException {
Date begin = new Date();
List<CompletableFuture<User>> futures = new ArrayList<>();
for (int i = 0;i<100;i++){
System.out.println("======="+i);
CompletableFuture<User> future = demoService.asyncMethod(i);
futures.add(future);
}
List<User> userList = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream().map(CompletableFuture::join).collect(Collectors.toList())).join();
Date end = new Date();
long interval = (end.getTime() - begin.getTime())/1000;
System.out.println("耗费时间:"+interval+"s");
System.out.println(userList.toString());
return userList.toString();
}
实现CompletableFuture的具体方法如下:
@Override
@Async
public CompletableFuture<User> asyncMethod(int i) throws InterruptedException {
User user = new User();
Thread.sleep(1000);
user.setId(i);
user.setName(i+"条");
System.out.println("-----"+user.toString());
return CompletableFuture.completedFuture(user);
}
返回结果如下所示:
耗费时间:13s
[User{name='0条', id=0, sex='null'}, User{name='1条', id=1, sex='null'}, User{name='2条', id=2, sex='null'}, User{name='3条', id=3, sex='null'}, User{name='4条', id=4, sex='null'}, User{name='5条', id=5, sex='null'}, User{name='6条', id=6, sex='null'}, User{name='7条', id=7, sex='null'}, User{name='8条', id=8, sex='null'}, User{name='9条', id=9, sex='null'}, User{name='10条', id=10, sex='null'}, User{name='11条', id=11, sex='null'}, User{name='12条', id=12, sex='null'}, User{name='13条', id=13, sex='null'}, User{name='14条', id=14, sex='null'}, User{name='15条', id=15, sex='null'}, User{name='16条', id=16, sex='null'}, User{name='17条', id=17, sex='null'}, User{name='18条', id=18, sex='null'}, User{name='19条', id=19, sex='null'}, User{name='20条', id=20, sex='null'}, User{name='21条', id=21, sex='null'}, User{name='22条', id=22, sex='null'}, User{name='23条', id=23, sex='null'}, User{name='24条', id=24, sex='null'}, User{name='25条', id=25, sex='null'}, User{name='26条', id=26, sex='null'}, User{name='27条', id=27, sex='null'}, User{name='28条', id=28, sex='null'}, User{name='29条', id=29, sex='null'}, User{name='30条', id=30, sex='null'}, User{name='31条', id=31, sex='null'}, User{name='32条', id=32, sex='null'}, User{name='33条', id=33, sex='null'}, User{name='34条', id=34, sex='null'}, User{name='35条', id=35, sex='null'}, User{name='36条', id=36, sex='null'}, User{name='37条', id=37, sex='null'}, User{name='38条', id=38, sex='null'}, User{name='39条', id=39, sex='null'}, User{name='40条', id=40, sex='null'}, User{name='41条', id=41, sex='null'}, User{name='42条', id=42, sex='null'}, User{name='43条', id=43, sex='null'}, User{name='44条', id=44, sex='null'}, User{name='45条', id=45, sex='null'}, User{name='46条', id=46, sex='null'}, User{name='47条', id=47, sex='null'}, User{name='48条', id=48, sex='null'}, User{name='49条', id=49, sex='null'}, User{name='50条', id=50, sex='null'}, User{name='51条', id=51, sex='null'}, User{name='52条', id=52, sex='null'}, User{name='53条', id=53, sex='null'}, User{name='54条', id=54, sex='null'}, User{name='55条', id=55, sex='null'}, User{name='56条', id=56, sex='null'}, User{name='57条', id=57, sex='null'}, User{name='58条', id=58, sex='null'}, User{name='59条', id=59, sex='null'}, User{name='60条', id=60, sex='null'}, User{name='61条', id=61, sex='null'}, User{name='62条', id=62, sex='null'}, User{name='63条', id=63, sex='null'}, User{name='64条', id=64, sex='null'}, User{name='65条', id=65, sex='null'}, User{name='66条', id=66, sex='null'}, User{name='67条', id=67, sex='null'}, User{name='68条', id=68, sex='null'}, User{name='69条', id=69, sex='null'}, User{name='70条', id=70, sex='null'}, User{name='71条', id=71, sex='null'}, User{name='72条', id=72, sex='null'}, User{name='73条', id=73, sex='null'}, User{name='74条', id=74, sex='null'}, User{name='75条', id=75, sex='null'}, User{name='76条', id=76, sex='null'}, User{name='77条', id=77, sex='null'}, User{name='78条', id=78, sex='null'}, User{name='79条', id=79, sex='null'}, User{name='80条', id=80, sex='null'}, User{name='81条', id=81, sex='null'}, User{name='82条', id=82, sex='null'}, User{name='83条', id=83, sex='null'}, User{name='84条', id=84, sex='null'}, User{name='85条', id=85, sex='null'}, User{name='86条', id=86, sex='null'}, User{name='87条', id=87, sex='null'}, User{name='88条', id=88, sex='null'}, User{name='89条', id=89, sex='null'}, User{name='90条', id=90, sex='null'}, User{name='91条', id=91, sex='null'}, User{name='92条', id=92, sex='null'}, User{name='93条', id=93, sex='null'}, User{name='94条', id=94, sex='null'}, User{name='95条', id=95, sex='null'}, User{name='96条', id=96, sex='null'}, User{name='97条', id=97, sex='null'}, User{name='98条', id=98, sex='null'}, User{name='99条', id=99, sex='null'}]
使用countDownLatch加Future进行实现
@GetMapping ("/testSyncTwo")
public String testSyncTwo() throws InterruptedException, ExecutionException {
Date begin = new Date();
List<Integer> initList = new ArrayList<>();
List<String> allStrList = new ArrayList<>();
for (int i= 0;i<100;i++){
initList.add(i);
}
List<Future<List<String>>> futures = new ArrayList<>();
CountDownLatch downLatch = new CountDownLatch(initList.size());
for (Integer e: initList){
User user = new User();
user.setId(e);
user.setName("编号"+e);
CompleteCellThread cellThread = new CompleteCellThread(downLatch,user);
Future<List<String>> submit = pool.submit(cellThread);
futures.add(submit);
}
downLatch.await();
for (Future<List<String>> future:futures){
allStrList.addAll(future.get());
}
System.out.println("===执行后:"+allStrList.toString());
Date end = new Date();
long interval = (end.getTime() - begin.getTime())/1000;
System.out.println("耗费时间:"+interval+"s");
return allStrList.toString();
}
Thread中的方法如下:
public class CompleteCellThread implements Callable<List<String>> {
private CountDownLatch countDownLatch;
private User user;
public CompleteCellThread(CountDownLatch countDownLatch, User user) {
this.countDownLatch = countDownLatch;
this.user = user;
}
@Override
public List<String> call() throws Exception {
List<String> resultList = new ArrayList<>();
Thread.sleep(1000);
if (user.getId()%2 == 0){
user.setSex("男");
}else {
user.setSex("女");
}
resultList.add(user.getSex());
countDownLatch.countDown();
return resultList;
}
}
执行结果如下
===执行后:[男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女, 男, 女]
耗费时间:50s