【问题标题】:Threading a recursive function线程化递归函数
【发布时间】:2015-10-30 05:28:37
【问题描述】:

我有这个递归函数,它可以在 URL 上找到 href 并将它们全部添加到全局列表中。这是同步完成的,需要很长时间。我试图用线程来做到这一点,但未能让所有线程写入一个列表。有人可以告诉我如何使用线程来做到这一点吗?

private static void buildList (String BaseURL, String base){
    try{
        Document doc = Jsoup.connect(BaseURL).get();
        org.jsoup.select.Elements links = doc.select("a");
        for(Element e: links){
            //only if this website has no longer been visited
            if(!urls.contains(e.attr("abs:href"))){
                //eliminates pictures and pdfs
                if(!e.attr("abs:href").contains(".jpg")){
                    if(!e.attr("abs:href").contains("#")){
                        if(!e.attr("abs:href").contains(".pdf")){
                            //makes sure it doesn't leave the website
                            if(e.attr("abs:href").contains(base)){
                                urls.add(e.attr("abs:href"));
                                System.out.println(e.attr("abs:href"));

                                //recursive call
                                buildList(e.attr("abs:href"),base);
                            }
                        }
                    }
                }
            }
        }
    } catch(IOException ex) {

    }

    //to print out all urls.

    /*      
     * for(int i=0;i<urls.size();i++){
     * System.out.println(urls.get(i));
     * }
     */
}

【问题讨论】:

  • 你的线程代码在哪里?
  • @redFIVE 我最初是作为可运行的。由于其他外部因素,Runnable 扩展不是一个可接受的解决方案。我没有其他方面的多线程经验,因此这个问题。
  • 你有没有想过尝试谷歌线程间通信方法?
  • @redFIVE 如果您不想提供帮助,那很好,请不要打扰我。我一直在尝试各种事情。这是一个我知道它可以正常工作的状态,我希望从这里获得帮助。
  • @redFIVE 虽然我同意 OP 可能会做更多的研究,但没有理由变得刻薄和咄咄逼人。如果您不喜欢这个问题,只需投反对票,如果您认为有必要,请标记,然后继续。

标签: java multithreading recursion


【解决方案1】:

这是ForkJoin 的一个很好的用例。它将通过非常简单的代码提供出色的并发性。

对于解析的一组url,使用Collections.synchronizedSet(new HashSet&lt;String&gt;());

您还可以创建一个比您拥有的内核数量更大的ForkJoinPool,因为这涉及到网络(通常的用法是每个线程都将以 ~100% 的速度执行工作)。

【讨论】:

  • 我对加入部分有点困惑。我真的需要在 Java 中加入线程吗?每个线程不依赖于另一个线程,当它用完要探索的 URL 时它将结束。我可以分叉而不用担心加入吗?
  • 您想要收集结果。这就是连接部分的用武之地。
  • 看到这是问题,我希望不同的线程在排除其他线程时删除其他线程的选项。 List 需要在运行时由所有线程实时更新。
  • 这应该不是问题。不过,您需要使用 Set 而不是 List
【解决方案2】:

使用来自并发包的任何集合来存储您从不同线程获得的值。数组块

一旦你将问题分解为分而治之的算法,你就可以使用 fork 和 join。

【讨论】:

    猜你喜欢
    • 2016-12-13
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    相关资源
    最近更新 更多