0

我有一些课。例如:

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();

}

但是主线程比其他线程结束得更快,并且变量列表为空。我应该怎么办?请帮助:)

向上。从 Internet 下载一些数据并不太快,这就是我创建多个线程的原因。

4

3 回答 3

3

您可以使用 java 并发包,而不是处理线程 API 的低级细节,并使用执行程序来处理线程(我不知道 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如果您的任务抛出异常,它会抛出异常,例如,如果页面不可用,我想可能会发生这种情况。

于 2012-08-06T13:03:27.340 回答
2

1.当你触发另一个线程时,它会在使用join()方法之后立即从网络获取数据并填充列表。

2. 在调用它的线程的方法有finish()join()之前,方法不会让下一行执行。 run()

3.因此main(),在填充列表之前不会执行您的方法,因为您曾经join()在另一个线程完成之前保持执行.....

于 2012-08-06T12:46:46.077 回答
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();
    }
于 2012-08-06T12:47:53.737 回答