0

こんばんは、

このメソッドからコンテンツを取得するさまざまな URL (約 500) のリストがあります

public static String getWebContent(URL url){
 // create URL, build HTTPConnection, getContent of page
}

この後、値などのコンテンツを取得する別の方法があります。現時点では、次のようにします。

List<URL> urls = new ArrayList<>();
List<String> webcontents = new ArrayList<>();
    for(URL url : urls){
         webcontents.add(getWebContent(url));
    }
// Futher methods to extract values from the webcontents

しかし、それを行うスレッドは 1 つしかないため、実際には多くの時間がかかります。マルチスレッドにしたかったのですが、どのようにするのが最善の方法なのかわかりません。

まず、すべてのスレッドの戻り値が必要ですが、Callable代わりに実装する必要がありRunnableますか?

また、異なるスレッドでメソッドを実行するにはどうすればよいですか? インデックス 0 で始まるスレッド、インデックス 50 で始まるスレッドなどがありますか? 1 つの URL を使い終わったら、フラグを true に設定しますか? それが私のやり方ですが、あまり効果的ではないと思います。最初の Web サイトに多くのコンテンツがある場合、最初のスレッドは他のスレッドよりもはるかに時間がかかる場合があります。

そして、すべてのスレッドが完了したら、データを 1 つのリストに戻すにはどうすればよいでしょうか? このような?

List<String> webcontent = new ArrayList<>();
    if(!t1.isAlive() && !t2.isAlive()){
        webcontent.add(t1.getData());
        webcontent.add(t2.getData());
    }

あなたが私の問題を理解して、私にヒントを与えてくれることを願っています:)どうもありがとう

4

3 に答える 3

1

おそらく、次のようなことを試すことができます。

public static List<String> getWebContents(final int threads, final URL... urls){
    final List<Future<String>> futures = new LinkedList<>();
    final ExecutorService service = Executors.newFixedThreadPool(threads);
    Arrays.asList(urls).forEach(
            url -> {
                final Callable<String> callable = () -> {
                    try{
                        return getWebContent(url);
                    }catch(IOException ex){
                        ex.printStackTrace();
                        return null;
                    }
                };
                futures.add(service.submit(callable));
            }
    );
    final List<String> contents = new LinkedList<>();
    futures.forEach(
            future -> {
                try{
                    contents.add(future.get());
                }catch(Exception ex){
                    ex.printStackTrace();
                }
            }
    );
    service.shutdown();
    return contents;
}

Java 8 を使用していない場合:

public static List<String> getWebContents(final int threads, final URL... urls){
    final List<Future<String>> futures = new LinkedList<Future<String>>();
    final ExecutorService service = Executors.newFixedThreadPool(threads);
    for(final URL url : urls){
        final Callable<String> callable = new Callable<String>(){
            public String call(){
                try{
                    return getWebContent(url);
                }catch(IOException ex){
                    ex.printStackTrace();
                    return null;
                }
            }
        };
        futures.add(service.submit(callable));
    }
    final List<String> contents = new LinkedList<String>();
    for(final Future<String> future : futures){
        try{
            contents.add(future.get());
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }
    service.shutdown();
    return contents;
}
于 2013-10-29T23:33:46.390 に答える
0

作業中のスレッドから値を取得する代わりに、作業中のスレッドが結果のコレクションに結果を格納できるようにします (List<String> webcontentそれであれ他のものであれ)。これには同期が必要な場合があることに注意してください。

于 2013-10-30T16:51:47.313 に答える