mfrancis107
mfrancis107

Reputation: 1401

How to run indefinite background process/thread with web application

I want to be able to start/pause/exit a background process from a web application. I want the process to run indefinitely.

A user would go to a webpage. Press a button to start the thread and it will keep running until a user tells it to stop.

I'm trying to determine the best tools to do this. I've looked at things like Quartz but I haven't seen any discussion as to whether or not something like Quartz would be good for an indefinite thread.

My first thought was to do something like this.

public class Background implements Runnable{
    private running = true;

    run(){
         while(running){
              //processing 
        }
    }

    stop(){
        running = false;
    }
}

//Then to start
Background background = new Background();
new Thread(background).start();
getServletContext().setAttribute("background", background);

//Then to stop
background = getServletContext().getAttribute("background");
background.stop();

I am going to test this out. But I am curious if there may be a better way to accomplish this.

Upvotes: 1

Views: 2344

Answers (1)

gaborsch
gaborsch

Reputation: 15748

First, all the Objects put into Context must implement Serializable.

I don't recommend to put the Background object into the context, rather create a BackgroundController class, with private boolean running = true; attribute. The getter and the setter should be synchronised, to prevent that the background thread and the web request thread would conflict. Similarly, the private boolean stopped = false; should be put into the same class.

I also made a few other changes, you must break the loop core into small units (like 1 iteration), to make it possible to stop the process somewhere in the middle of the activity.

The code would look like this:

public class BackgroundController implements Serializable {
    private boolean running = true;
    private boolean stopped = false;
    public synchronized boolean isRunning() { 
        return running; 
    }
    public synchronized void setRunning(boolean running) { 
        this.running = running; 
    }
    public synchronized boolean isStopped() { 
        return stopped; 
    }
    public synchronized void stop() { 
        this.stopped = true; 
    }
}
public class Background implements Runnable {
    private BackgroundController control;
    public Background(BackgroundController control) {
        this.control = control;
    }

    run(){
         while(!isStopped()){
              if (control.isRunning()) {
                   // do 1 step of processing, call control.stop() if finished
              } else {
                   sleep(100); 
              }
        }
    }

}

//Then to start
BackgroundController control = new BackgroundController();
Background background = new Background(control);
new Thread(background).start();
getServletContext().setAttribute("backgroundcontrol", control);

//Then to pause
control = getServletContext().getAttribute("backgroundcontrol");
control.setRunning(false);

//Then to restart
control = getServletContext().getAttribute("backgroundcontrol");
control.setRunning(true);

//Then to stop
control = getServletContext().getAttribute("backgroundcontrol");
control.stop();

Upvotes: 1

Related Questions