2014-02-28 29 views
0

我需要創建一個線程,作爲一個獨立的進程無限地運行Spring MVC控制器。安排無限線程

當控制器第一次被擊中時,線程將開始。每次控制器被擊中時我都不想重新安排時間。

@RequestMapping(method = RequestMethod.GET) 
public String runTask() { 

    //I want this to be scheduled first time controller is hit but 
    //I don't want it to rechadule every time it is hit again 
    ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(); 
     exec.scheduleAtFixedRate(new Runnable() { 
     @Override 
     public void run() { 
      // do stuff 
     } 
    }, 0, 5, TimeUnit.SECONDS); 


    return "Task was scheduled to run"; 
} 

Java Thread every X seconds

有沒有更好的方式來做到這一點?

回答

0

只需添加這控制器

@PostConstruct 
public void init(){ 
    //call executor here 
} 
+0

這會在構造函數初始化時執行,而不是在第一次命中時執行。它可能工作,如果控制器懶惰初始化。 –

+0

好吧,那麼保持布爾變量isExecutorStarted並在第一次命中後使其成爲true。 –

+0

我想不出比給出細節更好的方法。 –

0

可以爲線程執行器和控制器初始化執行類似下面分開的邏輯:

public class MapDecoratorQueue { 
    //inject it 
    MyXExecutor myXExecutor; 

    @RequestMapping(method = RequestMethod.GET) 
    public String runTask() { 
     myXExecutor.setRunning(true); 
     return "Task was scheduled to run"; 
    } 
} 

//Inject this into MapDecoratorQueue in spring config 
class MyXExecutor{ 
    private final ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(); 
    private volatile boolean isRunning = false; 

    public MyXExecutor(){ 
     exec.scheduleAtFixedRate(new Runnable(){ 

      @Override 
      public void run() { 
       if(isRunning){ 
        //do stuff 
       } 
      } 
     }, 0, 5, TimeUnit.SECONDS); 
    } 

    public void setRunning(boolean running) { 
     isRunning = running; 
    } 
} 

把你的運行邏輯isRunning值的檢查下。如果你不想啓動執行程序,直到你第一次啓動,你可以使用相同的方法,你可以從控制器調用一個方法,如果執行程序沒有初始化,它將初始化執行程序。

希望這會有所幫助。

+0

謝謝!這是否會導致NPE,因爲您沒有實例化MyXExecutor? – gumenimeda

+0

@gumenimeda:我提到過,你需要根據你的需要在你的spring配置中注入MyXExecutor(參見代碼中的註釋)。無論如何,我的意思是解決這個問題,我只是給了代碼不能運行的代碼。讓我知道它是否可以解決您的問題。如果沒有,我可以進一步研究它。 – Mak

+0

另外,希望我的回答足夠清楚並且有幫助,但如果最後一段需要更多細節,請告知我。我可以添加更多示例代碼。 – Mak