2015-12-23 2 views
0

Я пытаюсь выполнить код с задержкой в ​​1 секунду в моем сервлете Java. Мне нужно проверить условие, если отслеживание включено или выключено. Если он выключен, он переходит в другое и закрывает планировщик. Код как указано ниже.ScheduledExecutorService не показывает изменения в переменной

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    // TODO Auto-generated method stub 

    Map m=request.getParameterMap(); 
    Set s = m.entrySet(); 
    Iterator it = s.iterator(); 
    int index=0; 

     while(it.hasNext()){ 

      Map.Entry<String,String[]> entry = (Map.Entry<String,String[]>)it.next(); 

      String key    = entry.getKey(); 
      String[] value   = entry.getValue(); 

      System.out.println("Value is "+value[0].toString()); 
        switch(key) 
        { 
        case "RegId": 
         RegId=value[0].toString(); 
         break; 
        case "isTrackingRequested": 
         isTrackingRequested=Boolean.valueOf(value[0]); 
         break;  
     } 
    } 
    boolean isTrackingRequestednew=isTrackingRequested; 
    ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor(); 

     ses.scheduleAtFixedRate(new Runnable() { 
      @Override 
      public void run() { 

       // code to run 
       if(isTrackingRequestednew){ 
        try { 
         System.out.println("==========================================================================="); 
         System.out.println("new track status is "+isTrackingRequestednew); 
         System.out.println("==========================================================================="); 

         }catch(Exception e) 
         { 

         } 
        } 
       else 
       { 
        ses.shutdown(); 

       } 
      } 
     }, 0, 1, TimeUnit.SECONDS); 
} 

Теперь для того, чтобы остановить отслеживание моего заявления отправить isTrackingRequestednew как «ложь», то теперь это значение не получает изменилось. Я не знаю, почему это происходит. Пожалуйста, помогите мне.

+0

Флаг является локальным для этого метода, поэтому он будет меняться с каждым запросом. Кроме того, я думаю, что логика планирования/остановки задач должна быть в отдельном классе, а не в сервлете, и должна контролироваться переменной экземпляра. –

+0

@ Darshan Mehta, если я создаю переменную экземпляра и делегирую задачу некоторому методу класса, он будет формировать новый объект для каждого запроса (один для поворота «на», а другой для отключения «выключен»). Мне нужно обработать функцию отключения для того же пользователя, который невозможен, если я создам объект и делегирую каждый раз. Надеюсь, ты понял. – Devs

+0

@ DarshanMehta тоже я думал то же самое, но значение переменной не меняется. – Devs

ответ

0

Этот код не компилируется, вы не можете получить доступ к локальной (не конечной) переменной внутри внутреннего класса.
Каждый раз, когда в почтовом запросе создается новый ExecutorService, вместо его создания один раз за сеанс или объект отслеживания. Я не знаю, какова цель этой нити, так что я бы сохранить ваш странного стиль кода

private static class TrackingInfo { 
    final private AtomicBoolean status; 
    final private ScheduledExecutorService ses; 

    TrackingInfo(boolean flagStatus) { 
     this.status = new AtomicBoolean(flagStatus); 
     this.ses = Executors.newSingleThreadScheduledExecutor(); 
     ses.scheduleAtFixedRate(new Runnable() { 
      @Override 
      public void run() { 

       // code to run 
       if (status.get()) { 
        try { 
         System.out.println("==========================================================================="); 
         System.out.println("new track status is " + status.get()); 
         System.out.println("==========================================================================="); 

        } catch (Exception e) { 

       } 
       } else { 
        ses.shutdown(); 
       } 
      } 
     }, 0, 1, TimeUnit.SECONDS); 
    } 

    public void setStatus(boolean status) { 
     this.status.set(status); 
    } 
} 

использовать либо request.getSession().getAttribute(...)/setAttribute() провести эту TrackingInfo и работник внутри него и передать изменения флага в работник TrackingInfo.setStatus(newStatus) например, или вы можете иметь некоторую переменную Map в классе контроллера (не локальная переменная метода) и сохранить идентификатор отслеживания и связанный с ним TrackingInfo.
Имхо, если ваш реальный терминатор из отслеживания нити так просто, как в размещенном коде

else { 
    ses.shutdown(); 
} 

вам не нужно TrackingInfo вообще. Просто хранить (в сессии или кэш, как это описано выше) ссылка на планировщик и чем вы получаете isTrackingRequestednew с ложным значением в методе doPost, получить этот планировщик и завершение его как это

if (!isTrackingRequestednew) { 
    ScheduledExecutorService scheduler = (ScheduledExecutorService) request.getSession().getAttribute("trackingScheduler"); 
    if (scheduler != null) { 
     scheduler.shutdown(); 
    } 
} 

Вместо "trackingScheduler" вы можете использовать некоторый идентификатор отслеживания как идентификатор и отправить его с каждым запросом.
Обратите внимание, что вам также необходимо очистить старые планировщики, которые не были отключены должным образом из-за некоторых сетевых ошибок или чего-то еще.

+0

Что касается того, что вы предлагаете здесь, я вижу, что вы создали новый класс. Теперь, поскольку это сервлет, если мне нужно получить доступ к этому методу класса, мне нужно создать объект, а затем получить к нему доступ. Поступая таким образом, я создам новый объект каждый раз, когда я отправляю любой запрос на сервлет. Следовательно, я не смог бы остановить планировщик, так как у меня нет доступа к предыдущему объекту. – Devs

+0

Нет, поскольку я сказал 'использовать либо request.getSession(). GetAttribute (...)/setAttribute(), чтобы удерживать эту TrackingInfo 'и' или вы можете иметь некоторую карту' в своем сервлете. Создайте один раз и получите доступ к нему несколько раз. – dezhik

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