2014-03-30 1 views
0

Я инициализировал службу exectuor с N потоками. После завершения N потоков я хочу подождать некоторое время, а затем повторно использовать исполнителя с новым экземпляром N потоков. Как мне это сделать?Ожидание завершения потоков в службе исполнителя

Вот пример кода, я использую, что не удается:

 int NumberOfThreads=Integer.parseInt(PropertyHandler.getProperty("numberOfThreads")); 

     ExecutorService executor = Executors.newFixedThreadPool(NumberOfThreads); 
     log.info("Executor class has been initialized"); 
     while (true) { 

     jobStack = MrMestri.buildJobs(); 
     log.info("Creating a job stack of the search urls"); 
     if (jobStack.isEmpty()) 
     { 
      Thread.sleep(10000); 
     } 
     else { 
      int jobToken = 0; 
      while (jobStack.size() > 0) { 
      jobToken++; 
      MrRunnable worker = new MrRunnable(jobStack.pop()); 
      executor.execute(worker); 
      if (jobToken% Integer.parseInt(PropertyHandler.getProperty("totalTrends")) == 0)  { 
      log.info("All jobs for the clock cycle complete , waiting for next clock cycle to start. Number of jobs completed " + jobToken); 
      executor.shutdown(); 
      Thread.sleep(milliseconds); 

} 

Теперь, когда я использую ИСПОЛНИТЕЛЬ завершение работы, нет исполнителя выполнять свои темы. И мои потоки реализуют runnable.

Любая быстрая реакция была бы очень полезной. Спасибо.

+0

Может executor.awaitTermination? –

+0

Ожидание прекращения используется, когда u использует executor.shutdown(). Или, по крайней мере, то, что кажется или когда оно истекает. Я не знаю, в какое время я могу установить там, поскольку некоторые из моих ответов могут занять некоторое время. Поэтому я не думаю, что хочу пойти по этому маршруту. –

ответ

1

Проблема с ниже линии, которая находится внутри while цикла.

jobStack = MrMestri.buildJobs(); 

В этом случае ниже условия всегда будет возвращать ложь, потому что jobStack пусто не бывает, если вы хотите обработать следующие N задач

jobStack.isEmpty() 

Переместить это условие во внутреннем while петли и break внутреннего цикла, если условие соответствует для обработки следующих N задач.


Пример кода:

import java.util.Stack; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class Executor { 

    /** 
    * @param args 
    * @throws InterruptedException 
    */ 
    public static void main(String[] args) throws InterruptedException { 
     int NumberOfThreads = Integer.parseInt("10"); 

     ExecutorService executor = Executors.newFixedThreadPool(NumberOfThreads); 
     while (true) { 

      Stack<Job> jobStack = MrMestri.buildJobs(); 
      int jobToken = 0; 
      while (true) { 
       if (jobStack.size() > 0) { 
        jobToken++; 
        MrRunnable worker = new MrRunnable(jobStack.pop()); 
        executor.execute(worker); 
        if (jobToken % Integer.parseInt("4") == 0) { 
         // executor.shutdown(); 
         System.out.println("short waiting..."); 
         Thread.sleep(2000); 

        } 
       } else { 
        System.out.println("long waiting..."); 
        Thread.sleep(10000); 
        break; 
       } 
      } 
     } 
    } 
} 

class MrMestri { 

    public static Stack<Job> buildJobs() { 
     Stack<Job> stack = new Stack<Job>(); 
     stack.push(new Job("A")); 
     stack.push(new Job("B")); 
     stack.push(new Job("C")); 
     stack.push(new Job("D")); 
     stack.push(new Job("E")); 
     stack.push(new Job("F")); 
     return stack; 
    } 

} 

class MrRunnable implements Runnable { 
    private Job job; 

    public MrRunnable(Job j) { 
     job = j; 
    } 

    @Override 
    public void run() { 
     System.out.println(job.getName()); 
    } 
} 

class Job { 
    private String name; 

    public Job(String n) { 
     name = n; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 
+0

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

+1

Это решает проблему в исходном коде, но не является подходящим способом дождаться завершения потоков. Существует почти всегда лучший подход, чем вызов Thread.sleep, независимо от проблемы. См. Ответ invokeAll ниже. –

+0

Но мне это нужно, чтобы спать? invokeall сообщит мне, если все потоки закончены, но после этого мне все еще нужно использовать поток sleep. Итак, приведенный выше подход все еще не прав? –

3

Просто не выключайте своего исполнителя - используйте его повторно. Сформировать коллекцию ИХ задач вместо Runnable и использование:

executor.invokeAll 

Она будет выполнять все задачи и вернуться, как только все они сделаны. Если MrRunnable не ваш класс или по какой-либо причине он должен реализует Runnable вы можете просто преобразовать его в отзывной как:

new Callable<Void>() 
    { 
     @Override 
     public Void call() throws Exception { 
      worker.run(); 
      return null; 
     } 
    }; 

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

  • Нет связанных вопросов^_^