Java @Groovy中的异步不是异步
我的任务是使数据库写入异步。表面上听起来很简单,但我在网上得到的信息并没有那么有用,我从同事那里听到的是“异步很棘手”。所以,我希望得到一些比“玩一玩,直到你让它工作”更有用的东西。我的代码/调用如下所示:`Java @Groovy中的异步不是异步,java,asynchronous,groovy,spring-boot,Java,Asynchronous,Groovy,Spring Boot,我的任务是使数据库写入异步。表面上听起来很简单,但我在网上得到的信息并没有那么有用,我从同事那里听到的是“异步很棘手”。所以,我希望得到一些比“玩一玩,直到你让它工作”更有用的东西。我的代码/调用如下所示:` @EnableAsync @SpringCloudApplication //To run as a FAT JAR: //public class Application { // Only extend when running as WAR public class Applicat
@EnableAsync
@SpringCloudApplication
//To run as a FAT JAR:
//public class Application {
// Only extend when running as WAR
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}}
public class MyClass{
public void asyncCall(){
if(1==1){
DatabaseWriter.testAsync();
System.out.println("past DatabaseWriter.testAsync() method");
return;
}
}}
public class DatabaseWriter {
@Async
public static Future<Object> testAsync(){
Thread.sleep(10000);
println ("end of DatabaseWriter.testAsync() method");
return null;
}}
显然,原始方法调用正在等待testAsync()方法的返回。我正在寻找我做错了什么的方向。@Async注释只适用于来自spring上下文的bean,因为spring围绕Async方法创建代理。因此,如果您使用新关键字创建bean:
new DatabaseWriter();
或者,如果将@Async注释放在静态方法上,它将不起作用,因为将有原始方法而不是代理
这个例子很有效。要启动应用程序,只需运行main方法
@SpringBootApplication
@EnableAsync
public class Application extends AsyncConfigurerSupport {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("GithubLookup-");
executor.initialize();
return executor;
}
}
@Component
class AppRunner implements CommandLineRunner {
public static final Logger logger = LoggerFactory.getLogger(AppRunner2.class);
@Autowired
private DatabaseWriter writer;
@Override
public void run(String... args) throws Exception {
logger.info("--- start ---");
writer.testAsync();
logger.info("--- stop ---");
}
}
@Component
class DatabaseWriter {
@Async
public Future<Object> testAsync() throws InterruptedException {
Thread.sleep(5000);
AppRunner.logger.info("end of DatabaseWriter.testAsync() method");
return null;
}
}
与
并且将看到@Async不起作用。在WyMuT CoCHa和一些进一步的研究之间,我发现问题不仅仅在于@Async注释,而是带有该注释的类必须是一个bean,因此调用类没有创建带有“new”关键字的实例。我仍然不完全理解,但这让我更接近,我的代码也能正常工作。
@SpringBootApplication
@EnableAsync
public class Application extends AsyncConfigurerSupport {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("GithubLookup-");
executor.initialize();
return executor;
}
}
@Component
class AppRunner implements CommandLineRunner {
public static final Logger logger = LoggerFactory.getLogger(AppRunner2.class);
@Autowired
private DatabaseWriter writer;
@Override
public void run(String... args) throws Exception {
logger.info("--- start ---");
writer.testAsync();
logger.info("--- stop ---");
}
}
@Component
class DatabaseWriter {
@Async
public Future<Object> testAsync() throws InterruptedException {
Thread.sleep(5000);
AppRunner.logger.info("end of DatabaseWriter.testAsync() method");
return null;
}
}
writer.testAsync();
new DatabaseWriter().testAsync();