5

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

我想知道这一点,因为我找不到明确记录的方式来中止正在进行的 HTTP 连接。通过调用来中断工作线程是Thread.interrupt()行不通的,因为InputStream你从中获得HttpURLConnection的不是可中断的。

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

// 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()从另一个线程调用会有什么问题吗?

4

2 回答 2

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();
}
于 2014-04-01T11:04:45.123 回答
0

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

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

于 2014-10-20T19:19:49.473 回答