Я использовал такой пул потоков: new ThreadPoolExecutor(8, 8, 8, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(2048));
Запустите его и некоторое время отправляйте задачи параллельно, затем используйте FutureTask
для get
результата. Сначала это кажется нормальным, но все 8 потоков пула очень скоро переходят в состояние WAITING (парковка). Ни один поток не может быть запущен снова, и очередь задач становится все длиннее и длиннее. Я бегло смотрю на FutureTask.awaitDone()
и думаю, что, возможно, это код последней строки LockSupport.park(this)
вызывает такое состояние. Итак, что мне делать, чтобы избежать состояния для этих потоков?
Актуальные коды (проект на основе SpringBoot):
public class MyAsyncConfigurerSupport extends AsyncConfigurerSupport {
@Bean
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(8);
executor.setMaxPoolSize(8);
executor.setKeepAliveSeconds(8);
executor.setQueueCapacity(2048);
executor.setAllowCoreThreadTimeOut(true);
executor.setRejectedExecutionHandler((Runnable r, ThreadPoolExecutor exe) -> {
throw new RuntimeException("TooBusy");
});
return executor;
}
}
public class MyController {
@Autowired
private MyService service;
public String get(String key) {
Future<String> future = service.getSomeThing(key);
// numbers of same kind of futures
return future.get();
}
}
@Service
public class MyService {
@Async
public Future<String> getSomeThing(String key) {
// Call remote http server
String result = feignClient.callAPI(key);
return new AsyncResult<>(result);
}
}
getSomeThing
, а не просто краткую демонстрацию, код, который вы считаете неуместным, может быть важен для поиска проблемы - person neo   schedule 16.07.2020QueueCapacity=2048
, аThreadPoolTaskExecutor.createQueue
будет использоватьLinkedBlockingQueue
, Spring будет использовать этотThreadPoolTaskExecutor
для выполнения задачи при вызове метода с@Async
- person wangkui   schedule 16.07.2020