1、Callable
1)Runnable,执行独立的任务,但不返回值。如希望任务完成后有返回值,可以使用Callable接口实现;
2)Callable,是一个具有类型参数的范型,他的类型参数方法表示为方法call()而不是run()中返回的值,并且必须使用ExecutorService.submint()方法进行调用。
区别:
1.Callable,接受一个泛型,然后在call()方法中返回一个这个类型的值;然而,Runnable的run()方法无返回值;
2.Callable,其call()方法可抛出异常,而Runnable的run()方法是不抛出异常的。
2、业务场景:
HTTP请求中,业务处理流程耗时较长,比如大的查询,远程调用等场景,接受http请求的主线程会被一直占用,而tomcat线程池线程数量又是有限的,所以,单位时间内接受http请求量就会下降。
3、代码示例
1)controller
package com.liuxd.controller;
import com.liuxd.entity.Responses;
import com.liuxd.service.BusinessService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.Callable;
@Slf4j
@RestController
public class AsyncCallableController {
@Autowired
private BusinessService businessService;
@GetMapping(value = "/getData")
public Callable<Responses<String>> getData() {
log.info("收到HTTP请求...");
Callable<Responses<String>> data = (() -> {
return businessService.getData();
});
log.info("接收HTTP请求线程任务已完成,退出!");
return data;
}
}
2、service
package com.liuxd.service;
import com.liuxd.entity.Responses;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class BusinessService {
public Responses<String> getData(){
log.info("调用service方法,开始执行...");
try {
Thread.sleep(2500L);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("调用service方法,执行结束!!");
return new Responses<>(0,"操作完成","SUCCESS");
}
}
3)打印结果