В Java ExecutorService, как установить максимальное количество потоков, потребляемых запросом

1

Иногда мой сервер получает запрос, который может вызвать передачу 1000 заданий. При использовании threadpool я не хочу, чтобы более 15 потоков из threadpool потреблялись для задач из одного запроса.

Если я этого не делаю, это вызывает голод для других запросов.

Любые предложения о том, как это реализовать.

  • 2
    Ваш вопрос звучит немного неясным. Обычно используют ExecutorService (по сути, пул потоков), чтобы избежать создания потоков во время выполнения; однако вы говорите, что ваша задача может создавать потоки самостоятельно. Вы используете ForkJoinPool? В противном случае, пожалуйста, сообщите нам ваш вариант использования.
  • 0
    Aggreed. Я пытался уточнить. Нет просьба не порождает новые темы. Иногда они генерируют слишком много задач для выполнения.
Показать ещё 1 комментарий
Теги:
performance
multithreading

2 ответа

0

Вы должны проверить, сколько запросов ваше приложение может обрабатывать одновременно, чтобы запросы могли обрабатываться изящно. В общем, мы используем рабочие очереди для этих сценариев.

Фрагмент из книги "Java Concurrency in Practice":

Requests often arrive in bursts even when the average request rate is fairly stable. Queues can help smooth out transient bursts of tasks, but if tasks continue to arrive too quickly you will eventually have to throttle the arrival rate to avoid running out of memory.[4] Even before you run out of memory, response time will get progressively worse as the task queue grows

Сказав это, в вашем случае, возможно, вы можете использовать модель нить за запрос или модель threadpool-per-request.

0

Есть два случая для создания слишком большого количества запросов:

  1. Вашей системе действительно нужно много запросов для обработки. В этом случае нет способа, кроме как попытаться улучшить оборудование и настроить производительность своих индивидуальных задач.

  2. Ваши задачи могут быть сконфигурированы и объединены (что я чувствую запах для вас). Если это так, вы можете попробовать рабочего, которого я получил ниже, где он гарантирует, что только одно выполнение запускается в соответствии с многочисленными запросами, чтобы поставить задачу в ExecutorService. IDispatcher по сути является моей ExecutorService службой.

/**
 * This class ensures the given task is only dispatched once in the dispatcher.
 * 
 * @author Alex Suo
 *
 */
public class DispatchOnceWorker implements IDispatchWorker {

    /** Logger of the class. */
    private static final Logger LOG = LoggerFactory.getLogger(DispatchOnceWorker.class);

    /** The key of task. */
    private final String key;

    /** The actual task to be dispatched. */
    private final Runnable taskWrapper;

    /** The dispatcher working on. */
    private final IDispatcher dispatcher;

    /** The counter for task scheduling count. */
    private final AtomicInteger counter = new AtomicInteger();

    /**
     * Constructor.
     * 
     * @param key The dispatcher key for the task.
     * @param task The actual task to be executed/dispatched.
     * @param dispatcher The dispatcher working on.
     */
    public DispatchOnceWorker(final String key, final Runnable task, final IDispatcher dispatcher) {
        this.key = key;
        this.dispatcher = dispatcher;

        this.taskWrapper = new Runnable() {

            @Override
            public void run() {
                try {
                    counter.set(1);
                    task.run();
                } catch (Exception e) {
                    LOG.error("Error executing on dispatch key " + key, e);
                } finally {
                    if (counter.decrementAndGet() > 0) {
                        dispatcher.dispatch(key, this);
                    }
                }
            }

        };
    }

    @Override
    public void dispatch() {
        if (counter.getAndIncrement() == 0) {
            dispatcher.dispatch(key, taskWrapper);
        }
    }

}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню