传统做法
例如某个查询是一个组合查询,该查询结果是要返回一个json大对象,json大对象的每一块对应一个sql查询,常规 的操作可能是顺序查询,
new 一个对象,将每一次查询的sql 的结果赋值到json对象中,这种同步的顺序查询的做法耗时将会非常的大,做法如下
@Autowired
QueryService queryService;
/**获取水果价格
*/
@RequestMapping("/query/fruitPrice")
public Fruit queryFruitPrice() {
Fruit fruit=new Fruit();
/**
* 假设要查询水果的价格,需要执行三组不同的sql,才能查出每种的水果价格,查完之后,我们需要组装才能返回
* 这三种查询互补依赖,同步查询是在没有必要,而且耗时
*/
fruit.setApple(queryService.queryApple());
fruit.setBanana(queryService.queryBanana());
fruit.setOrange(queryService.queryOrange());
return fruit;
}
改成多线程查询(未使用CountDownLatch)
private static final ExecutorService es = Executors.newCachedThreadPool();
@Autowired
QueryService queryService;
/**获取水果价格
*/
@RequestMapping("/query/fruitPrice")
public Fruit queryFruitPrice() {
Fruit fruit=new Fruit();
/**
* 由传统的同步查询改为异步查询
* 再对查询结果进行组合返回
*/
Callable<Boolean> queryAppleCallable = new Callable<Boolean>() {
public Boolean call() throws Exception {
fruit.setApple(queryService.queryApple());
return true;
}
};
Future<Boolean> f1 = es.submit(queryAppleCallable);
Callable<Boolean> queryOrangeCallable = new Callable<Boolean>() {
public Boolean call() throws Exception {
fruit.setOrange(queryService.queryOrange());
return true;
}
};
Future<Boolean> f2 = es.submit(queryOrangeCallable);
Callable<Boolean> queryBananaCallable = new Callable<Boolean>() {
public Boolean call() throws Exception {
fruit.setBanana(queryService.queryBanana());
return true;
}
};
Future<Boolean> f3 = es.submit(queryBananaCallable);
//调用阻塞方法
try {
Boolean result1 = f1.get();
Boolean result2 = f2.get();
Boolean result3 = f3.get();
}catch(Exception e) {
log.info("查询出错");
}
return fruit;
}
多线程查询使用CountDownLatch
private static final ExecutorService es = Executors.newCachedThreadPool();
@Autowired
QueryService queryService;
/**获取水果价格
*/
@RequestMapping("/query/fruitPrice")
public Fruit queryFruitPrice() {
Fruit fruit=new Fruit();
//开启结果线程这个构造器的计数器值就写多少
CountDownLatch countDownLatch=new CountDownLatch(3);
es.execute(new Runnable() {
public void run() {
queryService.queryApple(fruit, countDownLatch);
}
});
es.execute(new Runnable() {
public void run() {
queryService.queryBanana(fruit, countDownLatch);
}
});
es.execute(new Runnable() {
public void run() {
queryService.queryOrange(fruit, countDownLatch);
}
});
try {
//等计数器减为0,也就是三个线程都执行完返回结果
countDownLatch.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return fruit;
}
@Service
public class QueryService {
public void queryApple(Fruit fruit,CountDownLatch countDownLatch){
//模拟从数据库查询
fruit.setApple(new Apple());
//计数器减一
countDownLatch.countDown();
}
public void queryBanana(Fruit fruit,CountDownLatch countDownLatch){
//模拟从数据库查询
fruit.setBanana(new Banana());
//计数器减一
countDownLatch.countDown();
}
public void queryOrange(Fruit fruit,CountDownLatch countDownLatch){
//模拟从数据库查询
fruit.setOrange(new Orange());
//计数器减一
countDownLatch.countDown();
}
}