2013-11-26 3 views
1

Вот моя задача. У меня статическая очередь заданий в классе и статический метод, который добавляет задания в очередь. Имейте n количество потоков, опрошенных в очереди и выполняющих задание. Мне нужно провести опрос n потоков одновременно с интервалом. AKA, все 3 должны опросить каждые 5 секунд и искать работу.Исполнитель и графикWithFixedDelay()

У меня есть это:

public class Handler { 

    private static final Queue<Job> queue = new LinkedList<>(); 

    public static void initialize(int maxThreads) { // maxThreads == 3 

     ScheduledExecutorService executorService = 
      Executors.newScheduledThreadPool(maxThreads); 

     executorService.scheduleWithFixedDelay(new Runnable() { 
      @Override 
      public void run() { 
       Job job = null; 
       synchronized(queue) { 
        if(queue.size() > 0) { 
         job = queue.poll(); 
        } 
       } 
       if(job != null) { 
        Log.log("start job"); 
        doJob(job); 
        Log.log("end job"); 
       } 
      }  
     }, 15, 5, TimeUnit.SECONDS); 

    } 

} 

Я получаю этот вывод, когда я добавляю 4 задачи:

startjob 
endjob 
startjob 
endjob 
startjob 
endjob 
startjob 
endjob 

Очевидно, что эти нити выполняют, что задания последовательно, в то время как мне нужно их сделать 3 за раз. Что я делаю не так? Благодаря!

+1

Действительно ли требуется опрос, или это просто деталь реализации, чтобы получить задания из вашей очереди в пул потоков? – Floegipoky

+0

Просто подсказка, но, вероятно, лучше отправить задачу с помощью 'Job' вместо синхронизации/опроса в Runnable on' queue'; этот вид побеждает цель параллельного выполнения. – raffian

ответ

2

Из документации:

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

Итак, вы должны запланировать три независимые задачи, чтобы они запускались одновременно. Также обратите внимание, что запланированная служба-исполнитель представляет собой фиксированный пул потоков, который недостаточно гибкий для многих случаев использования. Хорошая идиома заключается в том, чтобы использовать запланированную службу только для отправки заданий регулярной службе исполнителя, которая может быть настроена как изменяемый пул потоков.

+0

Удаленный ответ сказал, чтобы назвать scheduleWithFixedDelay() 3 раза. И это работает. Не знаю, почему он удалил его. Мне нужно оставаться на уровне 3 из-за системных ресурсов. Примите в мин. – jn1kk

+0

Интересно то же самое, ответ Джона был неплохим. –

0

Вы используете ScheduledExecutorService с фиксированной задержкой, что значит, что ваши задания будут работать один за другим. Используйте фиксированный пул потоков и отправьте 3 потока за раз. Вот an explanation with examples

0

Если вы объявляете Job extends Runnable, то ваш код упрощает драматический:

Первых объявить Исполнитель где-то глобально доступный:

public static final ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS); 

Затем добавить работу, как это:

executor.submit(new Job()); 

Вы сделали.

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