我正在研究一个解决方案,我正在尝试创建一个微服务,它立即返回响应,然后处理请求。
我正在尝试使用Java 8和Spring。
答案 0 :(得分:3)
以下是ExecutorService的示例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.annotation.PreDestroy;
import javax.servlet.http.HttpServletRequest;
@RestController
public class MyController {
// Instantiate an executor service
private ExecutorService executor = Executors.newSingleThreadExecutor();
@PreDestroy
public void shutdonw() {
// needed to avoid resource leak
executor.shutdown();
}
@GetMapping
public Object gerUrl(HttpServletRequest request) {
// execute the async action, you can use a Runnable or Callable instances
executor.submit(() -> doStuff());
return "ok";
}
private void doStuff(){}
}
您可以使用Executors工厂类来构建ExecutorService。这些方法可能会对您有所帮助:
java.util.concurrent.Executors
Executors.newSingleThreadExecutor() // jobs are queued and executed by a single thread
Executors.newCachedThreadPool() // new threads are instantiated as needed and cached
Executors.newFixedThreadPool(int nThreads) // user defined number of threads
@EnableAsync
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(MyApplication.class, args);
}
}
import javax.annotation.PreDestroy;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
public class AsyncConfiguration extends AsyncConfigurerSupport {
private ThreadPoolTaskExecutor executor;
@Override
public Executor getAsyncExecutor() {
executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(1000);
executor.initialize();
return executor;
}
@PreDestroy
public void shutdownExecutors() {
executor.shutdown();
}
}
@Service
public class MyService {
@Async
public void doStuff(){
// Async method
}
}
这两种技术都相当不错,但是第一个使用ExecutorService的技术可以为您提供更多控制。
答案 1 :(得分:2)
这可以通过多种方式实现。
为了在仍然执行长时间运行的同时从当前线程(在这种情况下为控制器)返回结果,您将需要另一个线程。
Executor
。控制器:
@Controller
public class AsyncController {
private AsyncService asyncService;
@Autowired
public void setAsyncService(AsyncService asyncService) {
this.asyncService = asyncService;
}
private ResponseEntity asyncMethod(@RequestBody Object request) {
asyncService.process(new MyLongRunningRunnable());
// returns immediately
return ResponseEntity.ok("ok");
}
}
一项服务:
@Service
public class AsyncService {
private ExecutorService executorService;
@PostConstruct
private void create() {
executorService = Executors.newSingleThreadExecutor();
}
public void process(Runnable operation) {
// no result operation
executorService.submit(operation);
}
@PreDestroy
private void destroy() {
executorService.shutdown();
}
}
更多细节可以在https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html
找到您只需使用@Async
,void
或Future
返回类型注释方法即可。
如果您仍想提供自己的执行程序,可以在spring配置bean中实现AsyncConfigurer
接口。
此方法还需要@EnableAsync
注释。
@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
return Executors.newSingleThreadExecutor();
}
}