Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.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中优雅地中断来自HTTP的流?_Java_Http_Thread Safety_Interrupt - Fatal编程技术网

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

如何在Java中优雅地中断来自HTTP的流?,java,http,thread-safety,interrupt,Java,Http,Thread Safety,Interrupt,我正在运行一个Java代码,它侦听一个长轮询HTTP流。 这就是我正在使用的方法 void connectStream() throws IOException, URISyntaxException { URIBuilder uriBuilder = new URIBuilder("..."); HttpGet httpGet = new HttpGet(uriBuilder.build()); HttpResponse response = h

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

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

当缓冲区通常包含数据时,这种方法效果很好。但是,如果缓冲区长时间保持空会怎样


我已经尝试关闭
读卡器
:程序不再在循环中执行代码,也不会退出循环。

解决了!我可以找到一种方法来获取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();
    }
}

您好@AlessioPalmeroAprosio-您需要知道被阻止的线程并中断它<代码>httpThread.interrupt()。。如果连接与任何类的实例之间存在1-1关系,则可以保存它。。然后
setInterrupt()
可以调用它,但如果不是,你需要说创建一个
FutureTask
或类似的东西,然后使用它们..当你说“interrupt”时,你的意思是(a)终止对传入流的处理,丢弃任何剩余的数据,还是(b)是否暂时暂停处理,但稍后从同一点继续?我猜你的意思是(a)基于代码,但请澄清事实并非如此。如果是(a),并且您在
reader.readLine()
中被阻止,则线程无法中断。从代码来看,每次调用
connectStream()
都是为了发出
get
请求,然后处理服务器返回的所有数据。您可以在自己的线程中运行每个这样的调用,而不必担心在没有可用数据时调用会暂停。当服务器关闭连接并且
readLine()
抛出IO异常时,每个这样的线程最终都会终止。@中断线程的MrR不会取消阻止
InputStream.read()
。嗯,好的点-@user207421-通过
Stream.close()
[我没有尝试过,但是…]-感觉有点糟糕,但理论上与另一端的死亡没什么不同。。。