Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多线程Java-暂停Web应用程序中长时间运行的任务_Java_Multithreading - Fatal编程技术网

多线程Java-暂停Web应用程序中长时间运行的任务

多线程Java-暂停Web应用程序中长时间运行的任务,java,multithreading,Java,Multithreading,我正在开发一个web应用程序,它需要执行一些长时间运行的任务(完成这些任务大约需要20分钟) 我希望它们在并行线程上运行,以便用户可以在任务运行时继续处理web应用程序中的其他内容 假设这是执行任务的类 public class TaskPerformer { public void performTask(String[] taskParameters){ // Long running task } } 我创建了一个像这样的线程类 public cl

我正在开发一个web应用程序,它需要执行一些长时间运行的任务(完成这些任务大约需要20分钟)

我希望它们在并行线程上运行,以便用户可以在任务运行时继续处理web应用程序中的其他内容

假设这是执行任务的类

public class TaskPerformer {

    public void performTask(String[] taskParameters){

        // Long running task

    }

}
我创建了一个像这样的线程类

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");
    }
}
现在,在我的web应用程序中,我在这个线程的基础上创建了一个新线程,并启动它,这样任务就可以在一个单独的线程上执行。这允许我的用户在我的webapp上继续他的一些其他作品

现在,我想在GUI上添加一个按钮来暂停和停止此任务

作为多线程新手,我读了一些书,发现我不能使用suspend()或resume(),因为它们被贬低了。因此,在我的其他试错会话中,我尝试实现一个简单的可暂停线程,如下所示:

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();
        }
    }
}
我实现了checkForPaused()方法来检查布尔标志,以检查是否需要暂停线程,并对静态变量执行wait(),只要布尔值没有更改

(我从这篇文章中得到了这个想法)

但是,解决方案中的陷阱是,我必须在循环的每次迭代中调用checkForPaused()。这意味着,我无法暂停我将要开始的长任务,因为我在一个线程中只会暂停一次


有人能提出我如何实现这一点的建议吗?

如果不反复调用checkForPaused,就无法从外部暂停线程,而不冒行为不一致的风险。suspend()和resume()被弃用的原因是,线程可能会在数据处于不一致状态时停止,因此唯一正确的方法是通知线程它应该暂停。但是这种情况发生的方式和时间应该只在线程本身中实现(因为只有线程知道数据何时处于一致状态)

可能的助手类:

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();
    }
}
在worker方法的对象中以及需要暂停/取消暂停线程的任何位置保留引用。定期在worker方法中调用isPaused()。

您可以使用

ProcessBuilder ps = new ProcessBuilder(...)
ps.start();
当你放弃它的时候

ps.destroy();
进一步阅读


您可以启动后台进程,可以随时终止该进程。在名为pause的线程上放置一个公共volatile布尔值。在您的任务中,反复检查暂停的布尔值并在暂停时休眠。@PeterLawrey谢谢,但您能解释一下我是如何做到这一点的吗?有什么参考依据吗?@bhspencer谢谢,但这正是我的问题。我不想定期检查标志,因为我必须跨包和类进行检查。还有其他选择吗?您所说的意思是,在我的performTask()方法中,我是否必须每隔一定时间检查一个标志才能暂停踏板。如果我的理解是正确的,那么如何获取TaskPerformer对象的标志值,因为它已经初始化,并且我有一个当前正在执行的方法。第二个问题是,没有其他办法吗???其他程序如何做到这一点?比如说像Eclipse这样的IDE。或者,如果我能处理当数据处于不一致状态时线程暂停时所面临的问题,我还能使用折旧方法吗?1。如果有办法绕过不推荐使用的方法,请不要使用它们。2.只需使用构造函数参数为TaskPerformer提供对帮助器引用的引用。