2011-04-30 87 views
4

我正在爲我的作業編寫代碼,我對編寫多線程應用程序並不太熟悉。我學會了如何打開一個線程並啓動它。我更好地展示代碼。Java多線程,如何停止?

for (int i = 0; i < a.length; i++) { 
    download(host, port, a[i]); 
    scan.next();       
} 

我上面的代碼連接到服務器打開a.length多個並行請求。換句話說,下載將打開a[i]連接,以在每次迭代中獲取相同的內容。但是,我希望我的服務器在i = 0完成下載方法並開始下一次迭代i = 1,此時已下載的線程已打開完成。我用scan.next()手動完成,但顯然這不是一個好的解決方案。我怎樣才能做到這一點?

編輯:

public static long download(String host, int port) { 
    new java.io.File("Folder_" + N).mkdir(); 
    N--; 
    int totalLength = length(host, port); 
    long result = 0; 
    ArrayList<HTTPThread> list = new ArrayList<HTTPThread>(); 
    for (int i = 0; i < totalLength; i = i + N + 1) { 
     HTTPThread t; 
     if (i + N > totalLength) { 
      t = (new HTTPThread(host, port, i, totalLength - 1)); 
     } else { 
      t = new HTTPThread(host, port, i, i + N); 
     } 
     list.add(t); 
    } 

    for (HTTPThread t : list) { 
     t.start(); 
    } 
    return result; 
} 

在我HTTPThread;

public void run() { 
    init(host, port); 
    downloadData(low, high); 
    close(); 
} 

注:我們的測試Web服務器是一個修改後的web服務器,它就會範圍:i-j並在響應中,有i-j文件的內容。

回答

5

您將需要調用正在下載的線程的join()方法。這將導致當前線程等待,直到下載線程完成。 This是一篇關於如何使用連接的好文章。

如果您想發表您的下載方法,你可能會得到一個更完整的解決方案

編輯:

好了,你開始你的線程後,你將需要加入他們的行列,像這樣:

for (HTTPThread t : list) { 
    t.start(); 
} 
for (HTTPThread t : list) { 
    t.join(); 
} 

這將停止方法返回,直到所有HTTPThreads完成

1

它可能不是一個好主意,以創建一個無界並行http請求數量無限的線程數。 (網絡套接字和線程都是操作系統資源,並且需要一些簿記開銷,因此在許多操作系統中都受到配額限制。另外,您正在閱讀的Web服務器可能不像1000個併發連接,因爲他的網絡套接字是也是有限的!)。

您可以用輕鬆地控制併發連接數的ExecutorService

List<DownloadTask> tasks = new ArrayList<DownloadTask>(); 
    for (int i = 0; i < length; i++) { 
     tasks.add(new DownloadTask(i)); 
    } 
    ExecutorService executor = Executors.newFixedThreadPool(N); 
    executor.invokeAll(tasks); 
    executor.shutdown(); 

這既是短,比你的自產自銷的併發限制更好,因爲你的限制將推遲開始下一批次直到所有當前批次的線程已完成。通過ExceutorService,每當舊任務完成時(即使還有任務),都會開始新任務。也就是說,您的解決方案將有1到N個併發請求,直到所有任務都已啓動,而ExecutorService將始終有N個併發請求。