Все потоки пула ОЖИДАЮТ (парковка)

Я использовал такой пул потоков: 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);
    }
}

person wangkui    schedule 16.07.2020    source источник
comment
Покажите нам реальный код — обычно его гораздо легче понять, чем просто описание кода.   -  person Amongalen    schedule 16.07.2020
comment
краткие актуальные коды уже здесь, спасибо.   -  person wangkui    schedule 16.07.2020
comment
покажите фактический код в методе getSomeThing , а не просто краткую демонстрацию, код, который вы считаете неуместным, может быть важен для поиска проблемы   -  person neo    schedule 16.07.2020
comment
На самом деле, там просто есть feignClient для вызова другого спокойного API-сервера.   -  person wangkui    schedule 16.07.2020
comment
Из кода, который вы опубликовали, я пропустил, где находится очередь задач и как вы вызываете исполнителя. Вы можете добавить это?   -  person Piro says Reinstate Monica    schedule 16.07.2020
comment
Я установил QueueCapacity=2048, а ThreadPoolTaskExecutor.createQueue будет использовать LinkedBlockingQueue, Spring будет использовать этот ThreadPoolTaskExecutor для выполнения задачи при вызове метода с @Async   -  person wangkui    schedule 16.07.2020


Ответы (1)


Извините, ребята, потому что мой проект огромен, поэтому приведенные выше фактические коды (я думаю, что это почти фактические коды) не являются настоящими фактическими кодами. Теперь я узнаю основную причину, и следующие простые коды могут ее воспроизвести.

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-го уровня, поэтому все они ОЖИДАЮТ (парковка)

person wangkui    schedule 27.07.2020