2016-12-01 2 views
1

Я пишу программу Java, которая должна контролировать несколько машин параллельно. Это число не фиксировано, оно может меняться (увеличиваться/уменьшаться) в любое время во время выполнения программы.Использование ExecutorService для параллельной обработки задач

Я думал сделать что-то вроде этого:

public static void main (String args[]) { 

    ExecutorService EXEC1 = Executors.newScheduledThreadPool(1); 

    EXEC1.scheduleWithFixedDelay(new Runnable() { 

     ExecutorService EXEC2 = Executors.new... 
     Map<Integer, Future<Void>> monitoringTasks = new HashMap<Integer, Future<Void>>(); 

     @Override 
     public void run() { 

      List<Machine> monitorizedMachines = MachineDao.getMonitorizedMachines(); 

      for (Machine machine: monitorizedMachines) { 

       Future<Void> monitoringTask = monitoringTasks.get(machine.getId()); 

       if(monitoringTask == null || monitoringTask.isDone()) { 

        monitoringTask = EXEC2.submit(new Runnable() { 
         @Override 
         public void run() throws Exception { 

          // monitor machine.... 

         } 
        }); 

        monitoringTasks.put(machine.getId(), monitoringTask); 
       } 

      } 
     } 

    }, 1, 1, TimeUnit.SECONDS); 

} 

Но возникли проблемы собирание наиболее подходящий Исполнителю (EXEC2) для этого случая: FixedThreadPool, CachedThreadPool, заказ реализации, ...

Он должен сказать, что каждая задача мониторинга составляет около 2/3 секунды.

Может ли кто-нибудь дать мне совет?

+0

У меня есть идея, я нужен код в вашем классе машины – toto

ответ

0

Большую часть времени, когда вы разрабатываете больших приложений на основе производства, вам нужно пойти с ExecutorService EXEC2 = Executors.newFixedThreadPool(THREAD_COUNT); и вам необходимо правильно настроить THREAD_COUNTпосле проведения тестов на производительность ш Ith ожидаемое число запросов/томов.

Вы можете посмотреть here для получения более подробной информации о том, почему newCachedThreadPool() НЕ идеален для приложений с большими объемами запросов.

0

Это простой пример. Сначала в вашем классе Машина добавьте пример публичной переменной boolean ISWORKING. В коде запуска() добавить свой код между переменной, как следующий пример:

public static class Machine implements Runnable { 

     public boolean ISWORKING = true; 

     @Override 
     public void run() { 
      this.ISWORKING = true; 
      //YOUR CODE HERE.................. 
      this.ISWORKING = false; 
     } 

    } 

Второй пример кода:

Timer timer = null; 
    TimerTask task = null; 
    boolean isLocked = false; 

    public void main() { 

     task = new TimerTask() { 

      @Override 
      public void run() { 

       if (isLocked) { 
        return; 
       } 

       isLocked = true; 

       List<Machine> monitorizedMachines = MachineDao.getMonitorizedMachines(); 

       //Count the pending job. 
       int poolsize = 0; 
       for (Machine machine : monitorizedMachines) { 

        if (!machine.ISWORKING) { 
         poolsize++; 
        } 

       } 

       if (poolsize == 0) { 
        isLocked = false; 
        return; 
       } 

       //Prevent a lot of poolsize. 
       poolsize = Math.min(100, poolsize); 

       ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(poolsize); 

       for (Machine machine : monitorizedMachines) { 

        if (!machine.ISWORKING) { 
         pool.execute(machine); 
        } 

       } 
       pool.shutdown(); 


       isLocked = false; 

      } 

     }; 

     timer = new Timer(); 
     timer.schedule(task, 1000, 2000); 

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