2012-08-06 38 views
0

我有一些類。例如:Java中的多線程

public class Data { 
    private String name; 

    public Data(String url) { 
     // There is download something from the Internet and set field "name". 
    } 

    public String getName() { 
     return name; 
    } 
} 

在某些方法中,我需要初始化對象數組的數據。

ArrayList<Data> list = new ArrayList<Data>; 
for(int i=0; i<max; i++) { 
    list.add(new Data("http://localhost/" + String.valueOf(i))); 
} 

但它是很長的。我想這樣做:

final ArrayList<Data> list = new ArrayList<Data>; 
for(int i=0; i<max; i++) { 
    final int tmp = i; 
    new Thread() { 

     public void run() { 
      list.add(new Data("http://localhost/" + String.valueOf(tmp))); 
     } 

    }.start(); 

} 

但主線程結束比其他人早,變量列表是空的。我該怎麼辦?請幫助:)

UP。從互聯網上下載一些數據並不是太快,這就是爲什麼我創建了多個線程。

+1

private ** type ** name? public ** type ** Data() – 11684 2012-08-06 12:45:11

+0

'「http:// localhost /」+ String.valueOf(tmp)'與'「http:// localhost /」+ tmp'相同 – Autar 2012-08-06 12:46:41

+4

你想要什麼實現?加快進程?在每個循環中啓動新線程只會讓你的程序變慢。如果你想並行化,把這個過程分解成智能的垃圾桶,比如每個10個垃圾桶。您必須在線程開銷和工作中的工作之間找到平衡點。 – alexsb 2012-08-06 12:47:08

回答

3

而不是處理線程API的底層細節,你可以使用java concurrent包,與執行處理的線程(我不知道什麼 ListArray是,但如果它不是線程安全的,您將遇到解決方案提出的一些其他答案的問題:添加一個連接是不夠的)。

例如,一個簡單的例子是:

final ExecutorService executor = Executors.newFixedThreadPool(10); 
final List<Future<Data>> list = new ArrayList<Future<Data>>(max); 

for (int i = 0; i < max; i++) { 
    final int tmp = i; 
    Callable<Data> c = new Callable<Data>() { 
     @Override 
     public Data call() { 
      return new Data("http://localhost/" + tmp); 
     } 
    }; 
    list.add(executor.submit(c)); 
} 

executor.shutdown(); 

for (Future<Data> future : list) { 
    Data data = future.get(); //will block until the page has been downloaded 
    //use the data 
} 

理想情況下,你對子級添加一些錯誤處理周圍future.get(),因爲它會拋出一個ExecutionException如果你的任務拋出一個異常,我想可能發生,如果例如該頁面不可用。

+0

非常感謝。你的例子非常有用和聰明。 – ruslanys 2012-08-06 13:14:46

2

當你觸發另一個線程,但這正從網上的數據,並填充列表,即使用join()方法後立即工作。

2.join()方法不會讓下一行來執行上調用它的線程的run()方法具有光潔度()之前。

所以你main()方法將不會被填充了名單之前,你已經使用join()其他線程完成之前舉行的執行執行.....

+4

這假定ListArray是線程安全的。 – assylias 2012-08-06 12:49:02

+0

謝謝你的理論。 – ruslanys 2012-08-06 13:14:22

+0

不客氣..... – 2012-08-06 15:52:26

1

在您的主要用途Thread.join等待子線程完成

Thread[] threads = new Thread[max]; 
    final List<Data> list = Collections.synchronizedList(new ArrayList<Data>()); 
    for(int i=0; i< max; i++) { 
     final int tmp = i; 
     Thread t = new Thread() { 

      public void run() { 
       list.add(new Data("http://localhost/" + String.valueOf(tmp))); 
      } 

     }; 
     t.start(); 
     threads[i] = t; 
    } 
    for (Thread t : threads) { 
     t.join(); 
    } 
+0

謝謝你的例子!很有用。 – ruslanys 2012-08-06 13:14:01