Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.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 我们如何停止后端进程?_Java_Multithreading_Spring Boot - Fatal编程技术网

Java 我们如何停止后端进程?

Java 我们如何停止后端进程?,java,multithreading,spring-boot,Java,Multithreading,Spring Boot,在我的spring boot应用程序中,我有以下REST服务 @GetMapping("/testThread") public Map<String, Object> testThread(HttpServletRequest request){ for (int i=0;i<100000;i++){ System.out.println(i); } return null; } @GetMapping(“/testThread”)

在我的spring boot应用程序中,我有以下REST服务

@GetMapping("/testThread")
public Map<String, Object> testThread(HttpServletRequest request){

    for (int i=0;i<100000;i++){
        System.out.println(i);
    }
    return null;
}
@GetMapping(“/testThread”)
公共映射测试线程(HttpServletRequest){

对于(int i=0;i您有两个原型选项,第一个是请求线程以某种方式取消请求。当您在返回响应之前进行工作时,理论上可以在每次迭代时向管道发送一些数据,例如,一个空格字符,然后刷新输出编写器。如果调用方关闭了管道,您将得到一个IOException,这将终止循环。但它非常有黑客性

另一种方法是返回工作线程的某种标识符,以便可以发送一个cancel命令来标识应该取消的线程。为此,您需要将工作线程推入一个新线程,并立即返回一个包含工作线程标识符的响应。这意味着初始客户端c即使工作线程仍在工作,all也会立即得到响应

请注意,下面的示例仅适用于单服务器或粘性负载平衡环境。当然,对于更复杂的体系结构,您可以将状态映射扩展到数据库表

您可能还希望添加更多端点以获取当前状态或结果

private enum State {
   Running,
   Cancel
}

private final Map<String, State> state = Collections.synchronizedMap(new HashMap<>());
private final ExecutorService executor = Executors.newCachedThreadPool();

@GetMapping("/cancelThread/{id}")
public Map<String, Object> testThread(@PathVariable String id) {
    state.computeIfPresent(id, (k, v) -> State.Cancel);
}

@GetMapping("/testThread")
public Map<String, Object> testThread(HttpServletRequest request) {
    String id = java.util.UUID.randomUUID().toString()
    state.put(id, State.Running);

    executor.submit(() -> doWork(id));

    Map<String, Object> response = new HashMap<>();
    response.put("transactionId", id);
    return response;
}

private void doWork(String id) {
    executor.submit(() -); 

    try {
        for (int i = 0; i < 100000; i++) {
          if (state.get(id) == State.Cancel) {
              break;
          }

          System.out.println(i);
        }
    } finally {
        state.remove(id);
    }
}
私有枚举状态{
跑步
取消
}
私有最终映射状态=Collections.synchronizedMap(新的HashMap());
private final executor Service executor=Executors.newCachedThreadPool();
@GetMapping(“/cancelThread/{id}”)
公共映射testThread(@PathVariable字符串id){
state.computeIfPresent(id,(k,v)->state.Cancel);
}
@GetMapping(“/testThread”)
公共映射测试线程(HttpServletRequest){
String id=java.util.UUID.randomUUID().toString()
state.put(id,state.Running);
执行人提交(()->doWork(id));
Map response=newhashmap();
response.put(“transactionId”,id);
返回响应;
}
私有无效doWork(字符串id){
执行人提交(()-);
试一试{
对于(int i=0;i<100000;i++){
if(state.get(id)=state.Cancel){
打破
}
系统输出打印LN(i);
}
}最后{
状态。删除(id);
}
}

您确实有这样做的选项。您尝试过什么?(另外,简单地说您抛出
中断异常
不会成功。您需要在循环中添加
if(Thread.currentThread().isInterrupted()){throw new InterruptedException();}
或类似内容。)@user2478398我已经更新了有问题的代码,删除了未使用的throws语句,你能建议一些好的链接来满足这个要求吗?谢谢你的回复。我需要一个建议,而不是状态映射,如果我使用数据库表,从性能上看,它不会像在每次循环迭代中一样好,我做一个Db查询来读取线程status correct?,所以我认为我应该使用map而不是db,这样我就可以将状态映射放在servlet上下文中,每当我需要访问映射时,我都会从servlet上下文中获取它,并且在再次更改状态后,将映射放在servlet上下文中。这样可以吗?放进某种集中服务的目的是如果您处于负载平衡的环境中环境中,取消请求可能不一定会命中工作程序正在运行的同一服务。或者,您可以考虑使用消息队列。但是,如果您只运行一台服务器,则可以在同一控制器中使用单个映射进行微调。在回答之前,我正在搜索我在下面找到的解决方案。.请看一看..在testThread方法中,我正在生成线程id thread.currentThread().getId(),我正在resp中返回该id,并且我在这里创建了另一个rest killThread,我正在传递thread id,在这个方法中,我正在终止特定的线程集setOfThread=thread.getAllStackTraces().keySet();for(thread thread thread:setOfThread){if(thread.getId()==threadId){thread.stop();}你能告诉我这会好还是不好吗?依赖线程id的问题是你不知道你在杀死什么。例如,如果我用线程id调用killThread,但是用id调用的线程不再处理原始工作负载,而是做一些完全不同的事情,因为线程本身或id都有错误,会发生什么已恢复?我已接受该答案..还有一个问题..如果我的doWork实现中没有任何循环,它将有数千行代码,那么此解决方案将如何工作或任何其他选项?