首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Unirest关机以退出程序

Unirest关机以退出程序
EN

Stack Overflow用户
提问于 2015-09-30 18:18:35
回答 2查看 3.6K关注 0票数 3

我尝试使用Unirest.get(...).asObjectAsync(...)更新具有计划任务的资源。要停止使用Unirest的程序,需要调用Unirest.shutdown();退出其事件循环和客户端。但是,如果一些线程在成功关闭之后调用Unirest的请求方法,则程序无法退出。

下面的代码是一个非常简单的示例:我启动一个线程,该线程在1.5秒后执行一个GET请求,并在它成功时打印状态消息。同时,在主线程上,Unirest被关闭。(请注意,这个示例使用asStringAsync(...)和一个非常简单的线程来简化。)

代码语言:javascript
运行
复制
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.async.Callback;
import com.mashape.unirest.http.exceptions.UnirestException;

import java.io.IOException;

public class Main {
    public static void main(String... args) throws IOException, InterruptedException {
        new Thread(() -> {
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Unirest.get("http://example.org").asStringAsync(new Callback<String>() {
                @Override
                public void completed(HttpResponse<String> response) {
                    System.out.println(response.getStatusText());
                }

                @Override
                public void failed(UnirestException e) {
                    System.out.println("failed");
                }

                @Override
                public void cancelled() {
                    System.out.println("cancelled");
                }
            });
        }).start();
        Unirest.shutdown();
    }
}

我所期望的是这些案件中的任何一个:

  • 程序关闭,没有输出。
  • 程序关闭,我得到任何这些输出:状态消息,失败或取消。
  • 程序关闭,但抛出一个异常,因为在发生GET请求时,Unirest已经关闭。

我得到的是:

  • 程序不关闭,GET请求成功,打印“确定”。

如何使用Unirest处理一个优雅的出口?我是否应该重组这个项目(如果是的话,如何重组)?

我在Windows上使用Java 8,在IntelliJ Idea 14.1.5中运行代码。我使用的最简单的依赖项是:

代码语言:javascript
运行
复制
<dependency>
    <groupId>com.mashape.unirest</groupId>
    <artifactId>unirest-java</artifactId>
    <version>1.4.7</version>
</dependency>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-21 22:38:53

在您的例子中,您已经生成了一个运行异步调用的线程。shutdown()调用位于主线程中,因此在调用线程生成时,shutdown()将在第一次调用Unirest的asStringAsync()方法之前被调用。

这是对..Async()的第一次调用,它实例化了最终需要关闭的线程池--在您调用关机方法时没有什么可关闭的,因此它是不操作的。它将在您创建的线程中实例化。

这里的解决方案是删除您创建的线程,并使用Unirest提供的Future对象。在执行异步调用时,Unirest处理线程本身,并且可以根据需要输入回调逻辑。

代码语言:javascript
运行
复制
    public static void main(String... args) throws IOException, InterruptedException, ExecutionException {
    Future<HttpResponse<String>> asyncCall = Unirest.get("http://thecatapi.com/api/images/get?format=xml&results_per_page=20").asStringAsync(new Callback<String>() {
        @Override
        public void completed(HttpResponse<String> response) {
            System.out.println(response.getStatusText());
        }

        @Override
        public void failed(UnirestException e) {
            System.out.println("failed");
        }

        @Override
        public void cancelled() {
            System.out.println("cancelled");
        }
    });
    HttpResponse<String> httpResponse = asyncCall.get(); // Can also use Future.isDone(), etc
    // System.out.println(httpResponse.getBody());
    Unirest.shutdown();
}
票数 1
EN

Stack Overflow用户

发布于 2020-06-23 19:54:40

asyncCall.get()将阻止调用,因此最好这样做:

代码语言:javascript
运行
复制
asyncCall.thenAcceptAsync((result)->{   
if (null != result && !result.isEmpty()) {
        // do your business logic after response and then close Unirest
        Unirest.shutdown();
         }
    });
   }

但是,在清理资源的情况下,您可以重复使用同一个已创建的资源,并注册一个关闭钩子,在JVM关闭期间清除所有内容。

参考资料:http://kong.github.io/unirest-java/#configuration

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32873070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档