私は Apache HttpComponents 4.2.1 を使用していますが、HttpGet.abort() と HttpPost.abort() を常にすぐに中止するのに問題があります。ほとんどの場合は機能しますが、タイムアウトするまで接続がブロックされることがあります。これは、タイムアウト値を明示的に設定した場合にのみ発生することに気付きました。
ここに私のテストコードがあります:
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
testAbort();
}
}
public static void testAbort() throws Exception {
String urlString = "http://slow.website.com";
final HttpGet httpGet = new HttpGet(urlString);
Runnable runnable = new Runnable() {
public void run() {
try {
HttpClient httpClient = new DefaultHttpClient();
HttpParams httpParams = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000); // issue doesn't occur if I comment this line
httpClient.execute(httpGet);
}
catch (Exception e) {
System.out.println(e.getMessage());
}
}
};
Thread t = new Thread(runnable);
t.start();
Thread.sleep(100);
httpGet.abort();
}
これが私が得る出力のサンプルです:
Request already aborted
Request already aborted
Request already aborted
Socket closed
Request already aborted
Connection has been shut down
Socket closed
Socket closed
Connect to slow.website.com:80 timed out
Connect to www.website.com:80 timed out
問題が発生することを確認するには、反復回数を増やすか、Thread.sleep() 値をいじる必要がある場合があります。
HttpComponent docs によると、「HTTP 要求が中止されると、I/O 操作でブロックされた実行スレッドは、InterruptedIOException をスローすることによってブロック解除されることが保証されます」(リンク)
Mac OS X 10.8 (Java バージョン 1.6.0_29) を実行しています。
問題の可能性があるアイデアはありますか?