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)打印結果