2015-12-23 94 views
0

我一直在嘗試在我的java servlet中執行延遲1秒的代碼。如果跟蹤打開或關閉,我需要檢查條件。如果它關閉,則轉到其他位置並關閉調度程序。代碼如下。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

該標誌對於此方法是本地的,因此它會隨着每個請求而改變。另外,我認爲計劃/停止任務的邏輯應該在一個單獨的類中,而不是在servlet中,並且應該由一個實例變量來控制。 –

+0

@Darshan Mehta如果我創建實例變量並將任務委派給某個類方法,它將爲每個請求(一個用於打開「on」和另一個用於關閉)形成新對象。我需要爲同一個用戶處理關閉功能,如果我每次都創建對象和委託,這是不可能的。我希望你明白我的觀點。 – 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.setStatus(newStatus)實例來保存這個TrackingInfo和裏面的工人,並通過標誌變化爲工人,或你可以在你的控制器類中有一些Map變量(不是方法局部變量),並且存儲跟蹤id和與之相關的TrackingInfo
恕我直言,如果你真正跟蹤線程的終止是簡單,因爲它是在發佈代碼

else { 
    ses.shutdown(); 
} 

你不需要TrackingInfo可言。 (因爲它是上述會話或高速緩存)參考簡單地存儲到調度器和比你在doPost方法獲得isTrackingRequestednew假值,得到這個調度和關閉它像這樣

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

相反"trackingScheduler"可以使用一些追蹤標識符作爲標識符併發送每個請求。
請注意,您還必須清理由於某些網絡錯誤或其他原因未正確關閉的舊調度程序。

+0

至於你在這裏建議什麼,我看你已經創建了一個新班級。現在,因爲它是一個servlet,如果我需要訪問這個類方法,我需要創建一個對象然後訪問它。通過這樣做,每當我發送任何請求到servlet時,我最終都會創建新對象。因此,我無法停止調度程序,因爲我無法訪問前一個對象。 – Devs

+0

不,正如我所說'使用request.getSession()。getAttribute(...)/ setAttribute()來保存這個TrackingInfo'和'或者你可以在你的servlet中有一些Map'。創建一次並訪問它無數次。 – dezhik