gpt4 book ai didi

java - 从 spring mvc 应用程序提交后台任务

转载 作者:搜寻专家 更新时间:2023-10-30 21:29:24 25 4
gpt4 key购买 nike

我已经有了可以工作的 Spring MVC 应用程序,接下来我要做的是从我的应用程序启动或提交后台任务。

基本上,即使用户决定在应用程序上做其他事情,我也想让任务继续进行直到它完成。

但如果需要,我也想停止/终止/暂停任务。因为我之前没有这样做过,所以我正在寻找一种好的/更好的方法来做到这一点。

我发现这些很有用:

http://blog.springsource.com/2010/01/05/task-scheduling-simplifications-in-spring-3-0/

How do you kill a thread in Java?

Java threads: Is it possible view/pause/kill a particular thread from a different java program running on the same JVM?

所以我想使用@Async 任务来提交我的后台任务,但又想使用线程的 ID 稍后获取它并在需要时停止它?

这是正确的方法吗?我没有任何多线程方面的经验,所以我来这里听听。

代码更新:

public interface Worker {
public void work();
public void cancel();
}

实现:

@Component("asyncWorker")
public class AsyncWorker implements Worker {

@Async
public void work() {
String threadName = Thread.currentThread().getName();
System.out.println(" " + threadName + " beginning work");
try {
Thread.sleep(10000); // simulates work
} catch (InterruptedException e) {
System.out.println("I stopped");
}
System.out.println(" " + threadName + " completed work");
}

public void cancel() { Thread.currentThread().interrupt(); }
}

用于测试目的的 Controller :

@ResponseBody
@RequestMapping("/job/start")
public String start() {
asyncWorker.work();
return "start";
}

@ResponseBody
@RequestMapping("/job/stop")
public String stop() {
asyncWorker.cancel();
return "stop";
}

当我访问/job/start 时,我无法同时执行多个任务。另一个只有在第一个完成后才开始执行

此外,当我访问 /job/stop 时,进程没有停止,我在这里错过了什么?

最佳答案

使用线程 ID 级别太低且脆弱。如果您决定使用 @Async annotation (不错的选择)你可以使用 Future<T> 来控制任务的执行。基本上你的方法应该返回 Future<T>而不是 void :

@Async
public Future<Work> work() //...

现在您可以 cancel()Future或等待它完成:

@ResponseBody
@RequestMapping("/job/start")
public String start() {
Future<Work> future = asyncWorker.work();
//store future somewhere
return "start";
}

@ResponseBody
@RequestMapping("/job/stop")
public String stop() {
future.cancel();
return "stop";
}

棘手的部分是存储返回的 future以某种方式对象,以便它可用于后续请求。当然,您不能使用字段或 ThreadLocal .您可以进行 session ,但请注意 Future不可序列化,不能跨集群工作。

@Async通常由线程池支持,很可能您的任务甚至还没有开始。取消只会将其从池中删除。如果任务已经在运行,您可以 isInterrupted()线程标志或句柄 InterruptedException发现cancel()打电话。

关于java - 从 spring mvc 应用程序提交后台任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12670720/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com