我正在尝试开发春季启动应用程序。我在没有弹簧框架的情况下将所有核心实现编写在Core Java中。我在这个春季启动应用程序中使用该罐子。我想管理我的休息控制器的并发。因此,在主类中相应地配置了ThreadPooltasKexecutor。理想情况下,我只需要2个并发请求才能进入execute()
方法,我注释了Async
。我一次测试了2个并发请求,但我在日志中看到我的请求一次都输入了execute()
。所有任务都是记忆密集型的。因此,由于堆内存问题而失败。我正在尝试找出理想的并发号码。我想知道我的配置是正确的还是我缺少一些东西?谢谢。
这是我的主要班级:
@SpringBootApplication
@EnableAsync
public class RestapiApplication implements AsyncConfigurer {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(RestapiApplication.class, args);
System.out.println("Rightdata Middleware ready to accept requests:");
}
@Bean(name = "executor1")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setMaxPoolSize(2);
taskExecutor.setCorePoolSize(2);
taskExecutor.setThreadNamePrefix("LULExecutor-");
taskExecutor.setQueueCapacity(100);
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}
这是我的休息控制器:
@RestController
@RequestMapping("/end2end")
public class End2EndRestController {
/**
* The log.
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
@RequestMapping(method = RequestMethod.POST)
public JSONObjectPOJO process(@RequestBody String end2EndScenarioString) throws InterruptedException, ExecutionException {
final JSONObjectPOJO jsonObjectPOJO = convertToJavaObject(end2EndScenarioString);
final ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable() {
@Override
public void run() {
try {
execute(jsonObjectPOJO);
} catch (Exception e) {
e.getMessage();
}
}});
executor.shutdown();
return jsonObjectPOJO;
}
@Async("executor1")
private void execute(JSONObjectPOJO jsonObjectPOJO) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(2);
Future<?> futureTarget;
Future<?> futureSource;
futureSource = processSource(executorService);
futureTarget = processTarget(executorService);
manageSourceProcessingResults(futureSource);
manageTargetProcessingResults(futureTarget);
executorService.shutdown();
//Do rest of the tasks.
}
@SuppressWarnings({"unchecked", "rawtypes"})
protected Future<?> processSource(executorService){
//Get appropriate class instance with call() - coreActionClass.
Future<?> futureSource = executorService.submit(coreActionClass);
return futureSource;
}
@SuppressWarnings({"unchecked", "rawtypes"})
protected Future<?> processTarget(executorService){
//Get appropriate class instance with call() - coreActionClass.
Future<?> futureTarget = executorService.submit(coreActionClass); //callable method in core.
return futureTarget;
}
private void manageSourceProcessingResults(Future<?> futureSource) {
try{
futureSource.get();
} catch(Exception e){
e.printStackTrace();
}
}
private void manageTargetProcessingResults(Future<?> futureTarget) {
try{
futureTarget.get();
} catch(Exception e){
e.printStackTrace();
}
}
}
更新 - 1:
我现在将代码更改为以下:
@RestController
@RequestMapping("/end2end")
public class End2EndRestController {
/**
* The log.
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
@RequestMapping(method = RequestMethod.POST)
public JSONObjectPOJO process(@RequestBody String end2EndScenarioString) throws InterruptedException, ExecutionException {
final JSONObjectPOJO jsonObjectPOJO = convertToJavaObject(end2EndScenarioString);
final ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable() {
@Override
public void run() {
try {
execute(jsonObjectPOJO);
} catch (Exception e) {
e.getMessage();
}
}});
executor.shutdown();
return jsonObjectPOJO;
}
}
和asyncservice类:
public class AsyncService {
@Async("executor1")
public void execute(JSONObjectPOJO jsonObjectPOJO) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(2);
Future<?> futureTarget;
Future<?> futureSource;
futureSource = processSource(executorService);
futureTarget = processTarget(executorService);
manageSourceProcessingResults(futureSource);
manageTargetProcessingResults(futureTarget);
executorService.shutdown();
//Do rest of the tasks.
}
@SuppressWarnings({"unchecked", "rawtypes"})
protected Future<?> processSource(executorService){
//Get appropriate class instance with call() - coreActionClass.
Future<?> futureSource = executorService.submit(coreActionClass);
return futureSource;
}
@SuppressWarnings({"unchecked", "rawtypes"})
protected Future<?> processTarget(executorService){
//Get appropriate class instance with call() - coreActionClass.
Future<?> futureTarget = executorService.submit(coreActionClass); //callable method in core.
return futureTarget;
}
private void manageSourceProcessingResults(Future<?> futureSource) {
try{
futureSource.get();
} catch(Exception e){
e.printStackTrace();
}
}
private void manageTargetProcessingResults(Future<?> futureTarget) {
try{
futureTarget.get();
} catch(Exception e){
e.printStackTrace();
}
}
}
- 我的理解是,当我配置
maxpoolsize(2)
时比2个请求一次是在execute()方法中。为一个新的请求输入,较早的请求之一必须完成其执行。我的理解正确吗?async
是否适用向内部执行人服务? - 我认为一次只处理2个请求,并且这些请求中的每一个都可以产生2个不同的线程并完成它的任务。请澄清。
我看到了两个问题。
1)在您的process
方法中,您正在创建一个新的执行权限服务。这不需要。而是在检索jsonObjectPOJO
之后只调用execute
方法。
2)您不能使用其实现的 @Async
int。您需要创建一个新类,让我们称为MyAsyncService
以包含@Async
方法。这是因为封面下正在进行的方面的编程。
查看此链接以获取更多信息。以下是链接的报价。
首先 - 让我们介绍规则 - @Async有两个限制:
它必须仅应用于公共方法 自我发电 - 从同一类中调用异步方法 - 无法正常工作 原因很简单 - 该方法需要公开,以便可以代理。自我发电不起作用,因为它绕过代理并直接调用基础方法。
编辑1:
@RestController
@RequestMapping("/end2end")
public class End2EndRestController {
@AutoWired
AsyncService asyncService;
private final Logger log = LoggerFactory.getLogger(this.getClass());
@RequestMapping(method = RequestMethod.POST)
public JSONObjectPOJO process(@RequestBody String end2EndScenarioString) throws InterruptedException, ExecutionException {
final JSONObjectPOJO jsonObjectPOJO = convertToJavaObject(end2EndScenarioString);
asyncService.execute(jsonObjectPOJO);
return jsonObjectPOJO;
}
public class AsyncService {
@Async("executor1")
public void execute(JSONObjectPOJO jsonObjectPOJO) throws Exception {
//No Futures, no ExecutorServices, just process that request.
}
}
通过创建和配置ThreadPooltasKexecutor仅使用2个线程,您就完成了目标。
edit2:spring @Async限制线程