【问题标题】:Retrieving data from multiple tasks from different threads从不同线程的多个任务中检索数据
【发布时间】:2013-10-31 00:51:47
【问题描述】:

晚上好,

我有一个不同 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

但实际上需要很多时间,因为只有一个线程在做。我想让它成为多线程的,但我不确定最好的方法是什么。

首先,我需要每个线程的返回值,我应该为它实现Callable而不是Runnable吗?

以及如何使用不同的线程运行该方法,是否应该有一个以索引 0 开头,一个以索引 50 开头,等等?当他们完成一个 URL 时,他们会设置一个标志为真吗?这将是我的方式,但我认为它不是很有效。如果第一个网站有很多内容,第一个线程可能需要比其他线程更长的时间。

当每个线程都完成后,我如何才能将我的数据返回到一个列表?像这样?

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

希望你能理解我的问题并给我一个提示:)非常感谢

【问题讨论】:

    标签: java multithreading threadpool


    【解决方案1】:

    您可以使用ExecutorCompletionService 在任务完成时检索它们。

    List<URL> urls = ...; // Create this list somehow
    ExecutorCompletionService<String> service =
        new ExecutorCompletionService<String>(Executors.newFixedThreadPool(10));
    for (URL url: urls) {
        service.submit(new GetWebContentCallable(url)); // you need to define the GetWebContentCallable
    }
    int remainingTasks = urls.size();
    while (remainingTasks > 0) {
        String nextResult = service.take();
        processResult(nextResult); // you define processResult
        remainingTasks -= 1;
    }
    

    【讨论】:

      【解决方案2】:

      也许您可以尝试以下方法:

      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;
      }
      

      【讨论】:

        【解决方案3】:

        不是从工作线程中检索值,而是让工作线程将结果放入结果集合中(无论是List&lt;String&gt; webcontent 还是其他任何东西)。请注意,这可能需要同步。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多