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

}

ただし、メインスレッドは他のスレッドよりも早く終了し、変数リストは空になります。私は何をすべきか?ヘルプpls:)

上。インターネットからデータをダウンロードするにはそれほど速くないので、いくつかのスレッドを作成しました。

4

3 に答える 3

3

スレッド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あります。これは、たとえばページが使用できない場合に発生する可能性があると思います。

于 2012-08-06T13:03:27.340 に答える
2

1.join()別のスレッドを起動すると、そのuseメソッドの直後に、ネットからデータを取得してリストにデータを入力する作業が行われます。

2. join()メソッドは、呼び出されたスレッドのメソッドがfinish()になる前に、次の行を実行させません。 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 に答える