4

Учитывая следующий класс:Как реализовать фиксированный коэффициент опроса с помощью ScheduledExecutorService?

public class Poller implements Runnable { 
    public static final int CORE_POOL_SIZE = 4; 

    public boolean running; 
    public ScheduledExecutorService ses; 

    public void startPolling() { 
     this.ses = Executors.newScheduledThreadPool(CORE_POOL_SIZE); 
     this.ses.scheduleAtFixedRate(this, 0, 1, TimeUnit.SECONDS); 
    } 

    public void run() { 
     running = true; 
     // ... Do something ... 
     running = false; 
    } 
} 

ScheduledExecutorService имеет основной размер пула потоков 4, но будет больше, чем один голосующий нить когда-либо будет создан? Так как this передано в scheduleAtFixedRate, значит ли это, что будет только один поток - или что-то более сложное происходит за кулисами?

и 2 бонус вопросы: -

  1. Если running быть static?
  2. Является CORE_POOL_SIZE избыточным?
+0

работа не может быть статичной –

+0

Пожалуйста, объясните ... –

+0

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

ответ

4

ScheduledExecutorService имеет основной размер пула потоков на 4, но будет больше, чем один голосующий нить когда-либо будет создан?

Это зависит - если вы запустите свою программу достаточно долго, она, вероятно, создаст 4 потока. Если вы оставите после выполнения запланированной задачи только один или два раза, вы можете увидеть только 2 или 3 потока.

Почему это имеет значение?

Один из способов контролировать создание потоков, чтобы обеспечить свой собственный ThreadFactory:

this.ses = Executors.newScheduledThreadPool(CORE_POOL_SIZE, new ThreadFactory() { 

      @Override 
      public Thread newThread(Runnable r) { 
       System.out.println("Creating thread"); 
       return new Thread(r); 
      } 
     }); 

Если работает быть статичным?

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

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

Является ли CORE_POOL_SIZE избыточным?

Не уверен, что вы имеете в виду. Это обязательный параметр, поэтому вам нужно указать значение. Если вы точно знаете, что два исполнения не будут выполняться одновременно, у вас может быть только один поток. Это также предотвратит параллельное выполнение (поэтому, если нужно запустить одну запланированную задачу, а другая уже запущена, новая будет отложена).

+0

Спасибо за полезный ответ. Тем не менее, все еще немного запутано. Я буду создавать экземпляр одного игрока. Итак, как создаются дополнительные потоки? Что касается избыточности q, я предполагаю из ответов, что за один раз может работать только один поток - так в чем смысл иметь более одного потока в пуле? –

+0

@SteveChambers Они создаются, потому что ScheduledThreadPoolExecutor создает новые потоки, пока не достигнет размера пула ядра.Единственная причина, по которой вам нужен только один поток, - это то, что вы хотите предотвратить одновременное выполнение своих задач (создание потоков очень дешево, с 1 или 4 потоками не будет сильно отличаться от перспективы производительности/памяти). Если нет, использование более одного потока поможет вашим задачам работать «вовремя», даже если ранее запланированная задача все еще выполняется. – assylias

+0

Думаю, я могу что-то упустить! Скажем, я создаю экземпляр 'poller', а затем вызываю' poller.startPolling() '. Он передает себя ('this') в' scheduleAtFixedRate() '. 'running' не является статическим и относится к одному экземпляру' poller', так что если имеется более одного потока, который представляет 'poller'? И как я узнаю, работает ли кто-нибудь из других? –

1

Почему вы предоставляете услуги администратора в категории Runnable? Вы должны отделить свой ScheduledExecutorService как Singleton, а не быть переменной класса runnable.

Напомните это ScheduledExecutorService представляет собой контейнер нити, поэтому, когда вы закодировать этот

this.ses = Executors.newScheduledThreadPool(CORE_POOL_SIZE); 

это создаст много нитей основы на значении размера в то же самое время, когда вы кладете этот код

this.ses.scheduleAtFixedRate(this, 0, 1, TimeUnit.SECONDS); 

ScheduledExecutorService случайным образом выбирает нить, которая бездействует для запуска этого класса каждые 1 секунду, пока не закончится. если вы ставите sleep в метод run, который длиннее значения периода времени, проходящего до запланированного потока, он не создаст другой поток до тех пор, пока не закончится 1-й поток. Так что если вы хотите несколько запустить эту Poller нить на то же время, а затем создать несколько Poller экземпляр и передать его в ScheduledExecutorService

CORE_POOL_SIZE его лишний не для меня, его хорошо, чтобы быть константой, значение которой берется из конфигурационного файла.

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

3

scheduleAtFixedRate (Runnable, длинные initialDelay, длительный период, TimeUnit TimeUnit) расписание

Этот метод задача выполняться периодически. Задача выполняется в первый раз после initialDelay, а затем повторяется каждый раз, когда истекает период.

Если какое-либо выполнение данной задачи вызывает исключение, задача больше не выполняется. Если исключений не выбрасывается, задача будет продолжаться до тех пор, пока функция ScheduledExecutorService не будет закрыта.

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

Смежные вопросы