我如何在 Java 中优雅地中断来自 HTTP 的流?

How can i gracefully interrupt a stream from HTTP in Java?

我是 运行 一个侦听长轮询 HTTP 流的 Java 代码。 这是我正在使用的方法。

void connectStream() throws IOException, URISyntaxException {

    URIBuilder uriBuilder = new URIBuilder("...");

    HttpGet httpGet = new HttpGet(uriBuilder.build());
    HttpResponse response = httpClient.execute(httpGet);
    HttpEntity entity = response.getEntity();
    if (null != entity) {
        InputStreamReader stream = new InputStreamReader((entity.getContent()));
        BufferedReader reader = new BufferedReader(stream);
        String line;
        while ((line = reader.readLine()) != null) {
            // do stuff
        }
    }
}

我需要从主线程优雅地中断这个流。最好的方法是什么? 现在,我添加了一个 AtomicBoolean 变量并在循环的每次迭代中检查它。

private AtomicBoolean interrupt = new AtomicBoolean(false);

void connectStream() throws IOException, URISyntaxException {

    URIBuilder uriBuilder = new URIBuilder("...");

    HttpGet httpGet = new HttpGet(uriBuilder.build());
    HttpResponse response = httpClient.execute(httpGet);
    HttpEntity entity = response.getEntity();
    if (null != entity) {
        InputStreamReader stream = new InputStreamReader((entity.getContent()));
        BufferedReader reader = new BufferedReader(stream);
        String line;
        while ((line = reader.readLine()) != null) {
            if (interrupt.get()) {
                break;
            }
            // do stuff
        }
    }
}

public void setInterrupt() {
    this.interrupt.set(true);
}

当缓冲区经常包含数据时,这很有效。但是,如果缓冲区长时间保持为空怎么办?

我已经尝试关闭 streamreader:程序不再执行循环内的代码,它不会退出循环。

已解决!我可以找到一种方法来获取 HTTP 连接下的套接字。通过关闭它,线程正确退出。

// No need this anymore
// private AtomicBoolean interrupt = new AtomicBoolean(false);

// New
private Socket socket;

void connectStream() throws IOException, URISyntaxException {

    URIBuilder uriBuilder = new URIBuilder("...");

    HttpGet httpGet = new HttpGet(uriBuilder.build());

    // New block code here
    HttpClientContext context = HttpClientContext.create();
    HttpResponse response = httpClient.execute(httpGet, context);
    ManagedHttpClientConnection connection = context.getConnection(ManagedHttpClientConnection.class);
    socket = connection.getSocket();

    HttpEntity entity = response.getEntity();
    if (null != entity) {
        InputStreamReader stream = new InputStreamReader((entity.getContent()));
        BufferedReader reader = new BufferedReader(stream);
        String line;
        while ((line = reader.readLine()) != null) {
            // do stuff
        }
    }
}

public void setInterrupt() {
    try {
        socket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}