【问题标题】:How to run indefinite background process/thread with web application如何使用 Web 应用程序运行无限期后台进程/线程
【发布时间】:2023-03-28 06:59:01
【问题描述】:

我希望能够从 Web 应用程序启动/暂停/退出后台进程。我希望进程无限期地运行。

用户会访问一个网页。按一个按钮启动线程,它会一直运行,直到用户告诉它停止。

我正在尝试确定执行此操作的最佳工具。我看过 Quartz 之类的东西,但我没有看到任何关于 Quartz 之类的东西是否适合无限期线程的讨论。

我的第一个想法是做这样的事情。

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();

我将对此进行测试。但我很好奇是否有更好的方法来实现这一点。

【问题讨论】:

  • 回答满意吗?

标签: java jakarta-ee web-applications glassfish


【解决方案1】:

首先,所有放入 Context 的Objects 必须实现Serializable

我不建议将 Background 对象放入上下文中,而是创建一个带有 private boolean running = true; 属性的 BackgroundController 类。 getter和setter应该是synchronised,防止后台线程和web请求线程冲突。同样,private boolean stopped = false; 应该放在同一个类中。

我还进行了一些其他更改,您必须将循环核心分解为小单元(如 1 次迭代),以便在活动中间的某个地方停止进程。

代码如下所示:

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();

【讨论】:

  • 您还应该考虑的事项:您希望如何启动Thread。在web容器中,不建议启动“独立”线程,最好使用一些线程池或者Quartz
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
  • 2020-08-11
  • 2013-08-09
  • 1970-01-01
相关资源
最近更新 更多