2013-04-17 25 views
4

如果我有一个java.net.HttpURLConnection在工作线程中接收数据(或即将接收数据),可以安全地呼叫disconnect()在另一个线程的连接生命周期的任何时刻停止它?可以从另一个线程安全地调用disconnect()来取消正在进行的HttpURLConnection?

我想知道这个,因为我找不到一个明确记录的方式来中止正在进行的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();  

看来工作,并且两个连接,它创建的Socket对象将通过GC最终被清理。不过,我想知道这是否是正确的做法?从另一个线程调用disconnect()会有什么问题吗?

回答

1

这将工作,如果你在任务中正确处理它。更好的方法是在从InputStream读取时检查任务的interruptState。

例如与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(); 
} 
0

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

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

+0

要解决此限制,请在[Future]中包含使用'HttpURLConnection'的代码,如[此处](http://stackoverflow.com/a/26489077/145173)所述。 –

相关问题