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

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

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请求成功,并显示“OK”。

  • 如何使用Unirest处理正常的退出?我应该重组程序(如果是,如何重组)?

    我在Windows上使用Java 8,在IntelliJ Idea 14.1.5中运行代码。
    我使用的unirest依赖项是:
    <dependency>
        <groupId>com.mashape.unirest</groupId>
        <artifactId>unirest-java</artifactId>
        <version>1.4.7</version>
    </dependency>
    

    最佳答案

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

    这是对..Async()的首次调用,它实例化了最终需要关闭的线程池-调用shutdown方法时没有要关闭的东西,因此它是无操作的。它将在您创建的线程中实例化。

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

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

    10-04 10:19