簡體   English   中英

線程加入在Android中不起作用?

[英]thread join not working in Android?

我編寫了可以與多個線程並行發送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

嗯...,您的代碼對我來說很好,加入后我看不到任何線程可以存活。 除非join拋出異常,否則在這種情況下,您的日志記錄語句不會觸發。

您是否在其他JVM或平台上嘗試過此操作?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM