简体   繁体   中英

MultiThreading Java - Pausing a long running tasks from a Web Application

I'm working on a web application which needs to perform some long running tasks (tasks that take around 20 minutes to complete).

I want them to run on a parallel thread, so that the user can keep working on something else within the web app while the task is running.

Assume this is the class that performs the task

public class TaskPerformer {

    public void performTask(String[] taskParameters){

        // Long running task

    }

}

I have created a thread class like this

public class TaskThread extends Thread {
    private TaskPerformer performer = new TaskPerformer();
    private String threadName;

    public TaskThread(String name){
        this.threadName = name;
    }

    public void run(){
        String[] params = {"Param1","Param2","Param3"};
        this.performer.performTask(params); // This might take 15-20 mins to complete
        System.out.println("Task completed successfully");
    }
}

Now, in my web app, I create a new thread based on this one, and start it, so that the task happens on a separate thread. This allows my user to carry on with some of his other works on my webapp.

Now, I would like to add a button on my GUI to pause and stop this task.

Being new to multi threading, I did some reading and found out that I can't use suspend() or resume() as they're depreciated. So in my other trial-and-error sessions, I tried to implement a simple pauseable thread like the one below:

public void run(){
    for(int i=10;i>0;i--){
        checkForPaused();
        System.out.println(this.threadName + " -- Counter -- " + i);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

I implemented the checkForPaused() method to check for a boolean flag to check if I need to pause a thread, and do a wait() on a static variable as long as the boolean is not changed.

(I got this idea from this post How to Pause and Resume a Thread in Java from another Thread )

But, the pitfall in the solution, is that I have to call the checkForPaused() in every iteration of my loop. Which means, that there is no way I can pause the long task I'm going to start, because I do that only once in a thread.

Can anyone suggest an idea how I can implement this?

If you don't call checkForPaused repeatedly, there is no way to pause your thread from the outside, without risking inconsistent behaviour. The reason why suspend() and resume() are deprecated is because the thread could be stopped at a moment where the data is in an inconsistent state, so the only way to do this right, is to notify the thread that it should be paused. But how and when this happens should only be implemented in the thread itself (because only the thread knows when the data is in a consistent state).

A possible helper class:

public class Helper {
    private volatile boolean flag;

    public synchronized void pause() {
        flag = true;
    }

    public synchronized void isPaused() {
        while(flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                // Set to false, so the thread can be interrupted (!= paused)
                flag = false;
            }
        }
    }

    public synchronized void continue() {
        flag = false;
        notify();
    }
}

Keep a reference in the object of your worker method and anywhere where you need to pause/unpause the thread. Call isPaused() in your worker method regulary.

You can use

ProcessBuilder ps = new ProcessBuilder(...)
ps.start();

and when you have given up on it

ps.destroy();

Further reading

https://stackoverflow.com/a/22362599/57695

How to Terminate a Process Normally Created using ProcessBuilder

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM