1 异步处理的优点
异步编程最大的特点是吞吐量大,延迟小,因为没有堵塞,这就容易挖掘现有硬件和操作系统等底层系统的潜力,同样的成本投入,异步系统要比传统铁板一块的同步系统更能应付爆发式涌潮的瞬间大流量
传统处理流程:
异步处理流程:
在tomcat 线程池中线程的数量的有限的,是线程达到上限请求就没法处理了。使用异步处理的话,主线程就可以空闲下来处理其他请求这样,服务器的吞吐量就会明显的提升。
2.同步处理
编写一个简单的controller 测试一下
@GetMapping
public String asyncSuccess() {
logger.info("主线程开始");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
logger.info("主线程结束");
return "success";
}
运行程序打出日志发现主线程消耗一秒钟多返回
3.runnable异步处理
使用callable方式编写测试controller代码
@GetMapping("/runnable")
public Callable<String> asyncSuccessRunnable() {
logger.info("主线程开始");
Callable<String> result=new Callable<String>(){
public String call() throws Exception {
logger.info("副线程开始");
Thread.sleep(1000);
logger.info("副线程结束");
// TODO Auto-generated method stub
return null;
}
} ;
return result;
}
运行程序打出日志发现主线程立即结束了,业务逻辑交给副线程去做了。
4.DeferredReult 异步处理
虽然上述的方法也能进行异步处理,但是有个很明显的确定就是副线程需要通过主线程去调用。但是在实际项目中场景是比上述的场景要复杂的多。
假设如下的场景
上述的方案就不好实现了下面用DeferredReult 实现上述的场景
定义一个controller进行处理服务
@GetMapping("/deferredReult ")
public DeferredResult<String> asyncSuccessDeferredReult () {
logger.info("主线程开始");
String orderNumber=RandomStringUtils.randomNumeric(8);
moQueue.setPlaceOrder(orderNumber);
DeferredResult<String> result=new DeferredResult<String>();
deferredResultHalder.getMap().put(orderNumber, result);
logger.info("主线程结束");
return result;
}
这里就不直接使用消息队列了定义一个类进行模拟
@Component
public class MockQueue {
private static final Logger logger = LoggerFactory.getLogger(MockQueue.class);
private String placeOrder;
private String complaceOrder;
public String getPlaceOrder() {
return placeOrder;
}
public void setPlaceOrder(String placeOrder) {
new Thread(()->{
logger.info("接到下单请求"+placeOrder);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.complaceOrder = placeOrder;
logger.info("下单请求处理完成"+placeOrder);
}).start();
}
public String getComplaceOrder() {
return complaceOrder;
}
public void setComplaceOrder(String complaceOrder) {
this.complaceOrder = complaceOrder;
}
}
定义DeferredResultHalder 封装处理
@Component
public class DeferredResultHalder {
private Map<String, DeferredResult<String>> map=new HashMap<String,DeferredResult<String>>();
public Map<String, DeferredResult<String>> getMap() {
return map;
}
public void setMap(Map<String, DeferredResult<String>> map) {
this.map = map;
}
}
定义一个监听 无限循环监听消息队列
@Component
public class QueueListener implements ApplicationListener<ContextRefreshedEvent>{
private static final Logger logger = LoggerFactory.getLogger(QueueListener.class);
@Autowired
private MockQueue moQueue;
@Autowired
private DeferredResultHalder deferredResultHalder;
public void onApplicationEvent(ContextRefreshedEvent event) {
//无限循环
new Thread(()->{
while(true) {
if(StringUtils.isNoneBlank(moQueue.getComplaceOrder())) {
String orderNumber=moQueue.getComplaceOrder();
logger.info("返回订单处理结果"+orderNumber);
deferredResultHalder.getMap().get(orderNumber).setResult("place order success");
moQueue.setComplaceOrder(null);
}else {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
运行项目打出日志如下
文章地址 http://www.haha174.top/article/details/258637
项目源码 https://github.com/haha174/imooc-security.git