1

Я пытаюсь Tune нить, которая делает следующее:ThreadPoolExecutor - ArrayBlockingQueue ... ждать, прежде чем она удаляет элемент формирования очереди

Нить бассейн только с 1 нить [CorePoolSize =0, maxPoolSize = 1]

Очередь используется является ArrayBlockingQueue

Quesize = 20

BackGround:
Поток пытается прочитать запрос и выполнить операцию над ним.

ОДНАКО, в конечном итоге запросы увеличились настолько, что поток всегда занят и потребляет 1 процессор, что делает его ресурсоемкой.

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

Что мне нужно сделать, так это спящий режим «операция», так что для каждой задачи поток спит когда-то и освобождает процессор.

Quesiton:
Однако, мне было интересно, если есть способ использовать очереди, которая в основном сам спит на некоторое время, прежде чем он читает следующий элемент. Это было бы идеально, так как спящая задача в середине исполнения, и выполнение неполного исполнения просто не кажется мне лучшим.

Пожалуйста, дайте мне знать, если у вас есть какие-либо другие предложения, а также для выполнения задач

Спасибо.

Edit: Я добавил последующий вопрос here исправлен размер maxpool быть 1 [написано в спешке] .. спасибо тим за указание его.

+1

На самом деле это не «ресурсный свиньи», есть много работы. Вы действительно хотите искусственно замедлить запросы? Почему запросы (клиенты?) Отправляются быстрее, чем их можно обработать? Это не является устойчивым. – AngerClown

+0

Хорошая точка. Если клиенты делают много запросов, которые отклоняются из-за полной очереди, они тратят впустую процессор, который мог бы быть лучше сбалансирован между клиентами и исполнителем. Очередь - это буфер для «сглаживания» нагрузки с течением времени; отклонения должны быть редкими, а не рутинными. – erickson

+0

Клиент не является специализированным клиентом реквестера в реальном смысле. У запрашивающего есть выделенный клиент, который масштабируется в соответствии с количеством запросов. Клиент, с которым я работаю, как дополнительный для ведения журнала, контролирует типы операций. После выборки все еще хорошо, чтобы получить изображение по запросам. Надеюсь, что это имеет смысл. – codeObserver

ответ

1

Нет, вы не можете заставить поток спать, пока он находится в бассейне. Если в очереди есть задача, она будет выполнена.

Приостановка в задаче с очередью - единственный способ заставить поток простаивать, несмотря на поставленные в очередь задачи. Теперь «спящий» не должен находиться в той же задаче, что и «работа» —, после каждой реальной задачи вы можете поставить отдельную задачу отдыха, что может привести к более чистой реализации. Что еще более важно, если работа - это Callable, которая возвращает результат, разделение на две задачи позволит вам получить результат как можно скорее.

В качестве уточнения, вместо того, чтобы спать в течение фиксированного интервала между каждой задачей, вы можете «дросселировать» выполнение до указанной скорости. Это позволит вам избежать ненужного ожидания между задачами, но не запускать слишком много задач в течение заданного интервала времени. Вы можете read another answer of mine для простого способа реализовать это с помощью DelayQueue.

1

Вы можете подкласс и переопределить ThreadPool beforeExecute спать в течение некоторого времени:

@Overrides 
protected void beforeExecute(Thread t, 
         Runnable r){ 
    try{ 
     Thread.sleep(millis); // will sleep the correct thread, see JavaDoc 
    } 
    catch (InterruptedException e){} 

    } 

Но увидеть комментарий AngerClown в об искусственно замедляя очередь, вероятно, не является хорошей идеей.

+0

Спасибо, Тило .. Я думаю, что beforeExecute может сделать трюк. Внесите изменения и примите ответ, если он отлично работает :). Сохранение потока открытым, если есть несколько идей :) – codeObserver

+0

+1 для упоминания метода beforeExecute. Люди иногда настолько одержимы абстракцией ExecutorService, что они склонны забывать о реализации ThreadPoolExecutor, и некоторые опрятные предложения тоже. –

+0

Я попытался возиться с этим подходом. Интересно, что @times вызывается beforeExecute(), а затем сразу выполняется задача без сна, а затем после истечения времени ожидания задача повторно выполняется. Я использую пул потоков, и есть только один поток [см. Подробности в моем вопросе] .. Я что-то упустил? – codeObserver

1

Это может не сработать для вас, но вы можете попробовать установить приоритет потока исполнителей на низкий.

По существу, создайте ThreadPoolExecutor с обычным ThreadFactory. Попросите метод ThreadFactory.newThread() Threads с приоритетом Thread.MIN_PRIORITY. Это приведет к тому, что сервис-исполнитель, который вы используете, должен быть запланирован только в том случае, если имеется доступное ядро ​​для его запуска.

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

+0

спасибо .. Я рассмотрел этот подход, но я боюсь, что он может голодать мою нить. Кроме того, мой поток пытается сэмплировать данные, поэтому мне нужна реальная картина мира о том, что происходит ... это может исказить образец только в те периоды, когда процессор низкий ..., который побеждает цель иметь поток. Кроме того, индивидуальная задача, выполняемая потоком, очень мала [но слишком много задач]. Поэтому я считаю, что сон может работать лучше. Согласовано ? – codeObserver

+0

Да, согласен. Я думаю, что решение Thilo лучше, поэтому я проголосовал за него. –

1

Причина, по которой поток потребляет 100% процессор, потому что ему дается больше работы, чем он может обрабатывать. Добавление задержки между задачами не решит эту проблему. Это только ухудшает ситуацию.

Вместо этого вы должны посмотреть, ПОЧЕМУ ваши задачи потребляют столько CPU, например. с профайлером и смените их так, чтобы потреблять меньше CPU, пока не обнаружите, что ваш поток может не отставать, и он больше не потребляет 100% -ный процессор.

+0

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

+0

@Javier, facebook не имеет никакого контроля над скоростью, с которой поступают запросы. Некоторые люди пытаются перегрузить сервер намеренно, чтобы узнать, что происходит. Ваш код может предполагать, что рабочая нагрузка является «более дружественной», –