我编写的代码可以使用多个线程以并行方式发送http请求。父线程使用thread.join()等待所有子线程完成。但在我的代码中,join()有时不起作用。有人能指出我的代码有什么问题吗?感谢。
/**
* @param urlSet
* , a set of link URLs (Can not be null)
* @return Map<link URL, response in byte array>
* @throws InterruptedException
*/
protected Map<String, byte[]> multiProcessRequest(Set<String> urlSet)
throws InterruptedException {
if (urlSet.isEmpty()) {
return null;
}
// Create and initialize HTTP parameters
HttpParams params = new BasicHttpParams();
ConnManagerParams.setMaxTotalConnections(params, MAX_CONNECTIONS);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
// Create and initialize scheme registry
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
// Create an HttpClient with the ThreadSafeClientConnManager.
// This connection manager must be used if more than one thread will
// be using the HttpClient.
ClientConnectionManager cm = new ThreadSafeClientConnManager(params,
schemeRegistry);
m_httpClient = new DefaultHttpClient(cm, params);
List<String> urlList = new ArrayList<String>(urlSet);
// create a thread for each URI
GetThread[] threads = new GetThread[urlSet.size()];
for (int i = 0; i < threads.length; i++) {
HttpGet httpget = new HttpGet(urlList.get(i));
threads[i] = new GetThread(m_httpClient, httpget, i + 1);
}
// start the threads
for (int j = 0; j < threads.length; j++) {
threads[j].start();
}
// join the threads
for (int j = 0; j < threads.length; j++) {
threads[j].join();
}
// FIXME: debug for statement only
for (int j = 0; j < threads.length; j++) {
if (threads[j].isAlive()) {
s_logger.debug("Thread " + (j+1) + " is still alive : " + threads[j].getState());
}
}
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
m_httpClient.getConnectionManager().shutdown();
s_logger.debug("ConnectionManager shutted down.");
/* Prepare the return. */
Map<String, byte[]> urlToResponseMap = new HashMap<String, byte[]>(
threads.length);
for (int i = 0; i < threads.length; ++i) {
urlToResponseMap.put(urlList.get(i), threads[i].getResult());
}
return urlToResponseMap;
}
/**
* A thread that performs a GET.
*/
static class GetThread extends Thread {
private final HttpClient httpClient;
private final HttpContext context;
private final HttpGet httpget;
private final int internalId;
/** The response result of the URL get. */
private byte[] result;
public GetThread(HttpClient httpClient, HttpGet httpget, int id) {
this.httpClient = httpClient;
this.context = new BasicHttpContext();
this.httpget = httpget;
this.internalId = id;
}
public byte[] getResult() {
return result;
}
/**
* Executes the GetMethod and prints some status information.
*/
@Override
public void run() {
s_logger.debug(internalId + " - about to get something from "
+ httpget.getURI());
try {
// execute the method
HttpResponse response = httpClient.execute(httpget, context);
s_logger.debug(internalId + " - get executed");
// get the response body as an array of bytes
HttpEntity entity = response.getEntity();
if (entity != null) {
result = EntityUtils.toByteArray(entity);
s_logger.debug(internalId + " - " + result.length
+ " bytes read from " + httpget.getURI());
s_logger.debug(internalId + ": " + result);
}
} catch (Exception e) {
httpget.abort();
s_logger.error(internalId + " - error: ", e);
}
}
}
在日志中,我在运行multiProcessRequest()后看到了这些调试消息:
D/GetThread:run( 964): 16 - get executed
D/GetThread:run( 964): 16 - 9444 bytes read from ......
D/dalvikvm( 964): GC freed 675 objects / 463256 bytes in 84ms
D/GetThread:run( 964): 16: [B@4383add8
D/GetThread:run( 964): 17 - get executed
D/GetThread:run( 964): 17 - 9000 bytes read from ......
D/GetThread:run( 964): 17: [B@437f5240
D/GetThread:run( 964): 18 - get executed
D/:multiProcessRequest( 964): Thread 18 is still alive : RUNNABLE
D/:multiProcessRequest( 964): Thread 20 is still alive : RUNNABLE
D/dalvikvm( 964): threadid=17 wakeup: interrupted
D/:multiProcessRequest( 964): ConnectionManager shutted down.
D/GetThread:run( 964): 18 - 9427 bytes read from ......
D/$GetThread:run( 964): 18: [B@438412e8
D/dalvikvm( 964): GC freed 1269 objects / 666456 bytes in 90ms
W/ExpatReader( 964): DTD handlers aren't supported.
D/$GetThread:run( 964): 20 - get executed
D/$GetThread:run( 964): 20 - 12751 bytes read ......
D/$GetThread:run( 964): 20: [B@43836dc0
以下这两行表明在join()之后仍有两个线程在运行:
D/:multiProcessRequest( 964): Thread 18 is still alive : RUNNABLE
D/:multiProcessRequest( 964): Thread 20 is still alive : RUNNABLE
答案 0 :(得分:1)
嗯......,你的代码对我来说很好看,我看不到你的联接之后有什么线程可以存活。除非join抛出异常,但在这种情况下,你的日志记录语句不会触发。
您是否在其他JVM或平台上尝试过此操作?