0

I need to create a thread that runs infinitely as a stand alone process withing Spring MVC controller.

The thread will start when the controller is hit for the first time. I don't want to reschedule every time controller is hit.

@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

Is there a better way to do this?

Community
  • 1
  • 1
gumenimeda
  • 815
  • 7
  • 15
  • 43

2 Answers2

1

You can separate the logic for thread execution and controller initializing the executor something like below:

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

Put your run logic under check of isRunning value. If you don't want to start the executor at all till you get first hit you can use the same approach and you can call a method from controller which will init the Executor if its not initialized.

Hope this helps.

Mak
  • 596
  • 5
  • 10
  • Thank you! Will this cause NPE because you are not instantiating MyXExecutor ? – gumenimeda Feb 28 '14 at 16:54
  • @gumenimeda: I have mentioned, you need to inject the MyXExecutor as per your need in you spring config (see the comment in code). Anyway my point here was to give solution to the problem and I just gave sample code not runnable code. Let me know if it solves your problem. If not I can further look into it. – Mak Mar 01 '14 at 00:37
  • Also, hope my answer is clear enough and helpful but let me know in case further details required for last paragraph. I can add more sample code. – Mak Mar 01 '14 at 00:58
0

just add this to controller

@PostConstruct
public void init(){
    //call executor here
}
Georgy Gobozov
  • 13,633
  • 8
  • 72
  • 78