2013-09-06 4 views
0

Проблема, с которой я столкнулся, проглатывает уже неделю, и вот она: У меня есть класс AdminBlocageBackgroundProcessing.java, который обрабатывает CSV-файл, читая данные из него и проверяя его и хранить его в списке массива, как:Отказ от вызова для ExecutorService никогда не завершается

public Object call() { 
    // TODO Auto-generated method stub 
    try{ 
    data = ImportMetier.extractFromCSV(
     new String(fichier.getFileData(), 
        "ISO-8859-1"),blocage); 

    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return data; 

}

И я зову его из моего класса действий с использованием:

ServletContext servletContext=getServlet().getServletContext(); 
ExecutorService execService = (ExecutorService)servletContext.getAttribute("threadPoolAlias"); 
AdminBlocageBackgroundProcessing adminBlocageBackgroundProcessing= new AdminBlocageBackgroundProcessing(fichier,blocage); 
if(status==0 && refreshParam.equals("eventParameter")) 
     { 
       future= execService.submit(adminBlocageBackgroundProcessing); 
       status=1; 
       autoRefControl=1; 
       req.setAttribute("CHARGEMENT_EN_COURS","chargement"); 
       return mapping.findForward("self"); 
     } 



     if(status==1) 
     { 
     // for checking if the submitted future task is completed or not  
     isFutureDone=future.isDone(); 

     if(isFutureDone) 
     { 
      data=future.get(); 
      status=0; 
      System.out.println("Process is Completed"); 
      req.setAttribute("TRAITEMENT_TERMINE","termine"); 
      //sessiondata.putBean(Constantes.BEAN_CONTRATCLIENT_CONTRAT_CLE_FIA, null); 
      //formulaire.set("refreshParam",""); 
      execService.shutdown(); 
      isFutureDone=false; 

     } 
     else{ 
      System.out.println("Les données sont encore en cours de traitement"); 
      req.setAttribute("CHARGEMENT_EN_ENCORE","encore"); 
      return mapping.findForward("self"); 
      } 
     } 

Теперь проблема заключается в том, что CSV имеет слишком много данных, и когда мы щелкаем по импорту, процесс запускается в фоновом режиме асинхронно, но он никогда не заканчивается, хотя он использовал autorefresh в jsp для поддержания сеанса. Как мы можем убедиться, что он завершен, хотя код работает отлично для небольших данных?
, но для больших данных эта функция рушится и не может контролироваться.

ThreadPool, который я использую обеспечивается контейнером:

public class ThreadPoolServlet implements ServletContextListener 
{ 

    public void contextDestroyed(ServletContextEvent arg0) { 
    final ExecutorService execService = (ExecutorService) arg0.getServletContext().getAttribute("threadPoolAlias"); 
    execService.shutdown(); 
    System.out.println("ServletContextListener destroyed"); 
    // TODO Auto-generated method stub 

} 
    //for initializing the thread pool 
    public void contextInitialized(ServletContextEvent arg0) { 
    // TODO Auto-generated method stub 
     final ExecutorService execService = Executors.newFixedThreadPool(25); 
     final ServletContext servletContext = arg0.getServletContext(); 
     servletContext.setAttribute("threadPoolAlias", execService); 
     System.out.println("ServletContextListener started");   
} 

}

ответ

0

Имел быстрый взгляд .. ваш isFutureDone зависит от status, которая выполняется сразу после подачи из задача - это довольно быстро. status обновляется только один раз и не обновляется повторно. Это хорошо в случае очень коротких, казалось бы, мгновенных задач, хотя оно будет ломаться для больших задач. Он ломается, потому что вы используете метод future.get условно на основе isFutureDone, который будет ложным для более длинных задач. Таким образом, вы никогда не получите get результат, хотя ваша задача выполнена в исполнителе. Уберите isFutureDone. Прочитайте немного по [Future.get][1] (обе версии [с и без таймаута] блокируют, что вам нужно здесь - дождаться завершения задачи). Было бы неплохо использовать тайм-аут в вашем коде, который вызывает службу CSV, чтобы позволить сбой, если он занимает слишком мало времени.