2016-12-01 40 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);,你需要進行性能測試瓦特第i個請求/卷的預期數量後正確地配置THREAD_COUNT

關於爲什麼newCachedThreadPool()不適用於大量請求的應用程序,您可以看看here

0

這是一個簡單的例子如何。 首先在你的機器上添加例子一個公共變量boolean ISWORKING。在run()的代碼添加變量之間的代碼像下面的例子:

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); 

    }