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;
}
}
在某些方法中,我需要初始化对象数组Data。
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。从互联网下载一些数据并不是太快,这就是为什么我创建了几个线程。
答案 0 :(得分:3)
不是处理Thread API的低级细节,而是使用java并发包,使用执行程序来处理线程(我不知道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
,如果页面不可用,我想这可能会发生。< / p>
答案 1 :(得分:2)
1。当您使用join()
方法之后立即触发另一个线程,该线程执行从网络获取数据并填充列表的工作。
2。 join()
方法不会让下一行在 run()
方法之前执行叫做finish()。
3。因此,在填充列表之前不会执行main()
方法,因为在完成其他线程之前使用join()
来保持执行。 ...
答案 2 :(得分: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();
}