I used a thread pool like this: new ThreadPoolExecutor(8, 8, 8, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(2048));
Run it and submit tasks in parallel for a while, then use FutureTask
to get
the result. It seems normal at the beginning, but all of the 8 threads of the pool become WAITING (parking) state very soon. No any one thread could be running again and the task queue become more and more longer.
I look at the FutureTask.awaitDone()
briefly, I think maybe it's the last line code LockSupport.park(this)
cause this state.
So, what should I do to avoid the state for these threads?
Actual codes(Project based on 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);
}
}
Another kind of deadlock endless loop (fixed on new version of jdk, replaced with a Recursive update Exception
):
Map<String, Object> concurrentMap = new ConcurrentHashMap<>();
concurrentMap.computeIfAbsent("ABC", k -> {
Object obj = new Object();
concurrentMap.put("ABC", obj);
return obj;
});
Sorry guys, because my project is huge, so the actual codes above (which I think is the actual codes almost) is not the real actual codes. Now I find out the primary cause and these simple codes following could reproduce it.
Just because there has nestification of async execute. The 1st level tasks used all of the threads, then the 2nd level tasks have no chance to be executed, but the 1st level tasks are waiting for the results of 2nd level tasks, so, all of them are WAITING (parking)