0

我使用了这样的线程池: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);
    }
}
4

2 回答 2

0

对不起,因为我的项目很大,所以上面的实际代码(我认为几乎是实际代码)不是真正的实际代码。现在我找出了主要原因,下面的这些简单代码可以重现它。

public static void main(String[] args) {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(4);
    executor.setMaxPoolSize(4);
    executor.setKeepAliveSeconds(4);
    executor.setQueueCapacity(1024);
    executor.setBeanName("AA");
    executor.setRejectedExecutionHandler((Runnable r, ThreadPoolExecutor exe) -> {
        throw new RuntimeException("TooBusy");
    });
    executor.initialize();

    for (int i = 0; i < 4; i++) {
        executor.execute(() -> {
            Future<Long> f = executor.submit(System::currentTimeMillis);
            try {
                f.get();
            } catch (Exception e) {
            }
        });
    }
}

只是因为有异步执行的嵌套。1级任务使用了所有线程,2级任务没有机会执行,但是1级任务在等待2级任务的结果,所以,都是WAITING(停车)

于 2020-07-27T04:04:25.427 回答
0

另一种死锁:

        Map<String, Object> concurrentMap = new ConcurrentHashMap<>();
        concurrentMap.computeIfAbsent("ABC", k -> {
            Object obj = new Object();
            concurrentMap.put("ABC", obj);
            return obj;
        });
于 2022-03-03T09:06:33.967 回答