【问题标题】:Can disconnect() be safely called from another thread to cancel an ongoing HttpURLConnection?可以从另一个线程安全地调用 disconnect() 以取消正在进行的 HttpURLConnection 吗?
【发布时间】:2013-04-17 19:28:57
【问题描述】:

如果我有一个在工作线程中接收数据(或即将接收数据)的java.net.HttpURLConnection,那么在另一个线程中的连接生命周期的任何时候调用disconnect() 来停止它是否安全?

我对此感到疑惑,因为我找不到明确记录的方法来中止正在进行的 HTTP 连接。通过调用Thread.interrupt() 来中断工作线程将不起作用,因为您从HttpURLConnection 获得的InputStream 是不可中断的。

我做了一些看起来像这样的实验:

// MyRequest.run() gets an HttpURLConnection by calling someUrl.openConnection()
MyRequest request = new MyRequest(someUrl);

FutureTask<SomeResult> task = new FutureTask<SomeResult>(request);
someExecutor.execute(task);

// The connection opens, data comes in, ...

// Get the HttpURLConnection from the request, call disconnect()
// Should be part of the cancel() of a FutureTask subclass
request.getConnection().disconnect();    

它似乎工作了,它创建的连接和套接字对象最终都会被 gc 清理掉。不过,我想知道这是否是正确的做法?从另一个线程调用disconnect()会有什么问题吗?

【问题讨论】:

    标签: java android


    【解决方案1】:

    如果您在任务中正确处理它,这将起作用。更好的方法是在读取 InputStream 时检查任务的中断状态。

    以 BufferedReader 为例:

    HttpURLConnection conn = null;
    try {
    
          //open Connection
    
       BufferedReader br = new BufferedReader(new InputStreamReader(inputstream));
       for(String line = br.readLine(); line != null && !Thread.currentThread().isInterrupted(); line = br.readLine()) {
             //do something
       }
    } catch(IOException io) {
         //error handling
    } finally {
       if(conn != null)
              conn.disconnect();
    }
    

    【讨论】:

    • 这仅在服务器开始返回数据后才有效。当客户端仍在等待响应时,它无济于事。
    【解决方案2】:

    HttpURLConnection 的文档说:“此类的实例不是线程安全的。”由于disconnect 是一个实例方法,因此根据文档,您不能在调用与该对象相关的任何其他方法时调用它。通常,I/O 线程代码几乎总是调用与 HttpURLConnection 相关的方法,因为这些方法在等待网络时会阻塞。

    如果您进行并发调用,例如一般的线程安全违规,当您在最重要的客户面前测试失败时,您可以期望它能够完美运行。 :-)

    【讨论】:

    • 要解决此限制,请将使用HttpURLConnection 的代码包装在Future 中,如here 所述。
    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多