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;
});