同时启动多个线程

时间:2013-12-27 07:12:47

标签: java multithreading

我有一个不同的网址列表(大约10个),我需要从中获取内容。我已经制作了一个程序,我正在通过该程序获取1个URL的内容,但我无法使用多个URL。

我已经学习了很多关于Java中线程的教程,但我找不到答案。

就我而言,网址就像www.example1.comwww.example2.comwww.example3.comwww.example4.com

我想为每个URL创建线程并同时运行它。

public class HtmlParser {
    public static int searchedPageCount = 0, 
                      skippedPageCount = 0,
          productCount = 0;

public static void main(String[] args) {

    List<String> URLs = new LinkedList<String>();

    long t1 = System.currentTimeMillis();

    URLs.add("www.example.com");

    int i = 0;
    for (ListIterator iterator = URLs.listIterator(); i < URLs.size();) {
        i++;
        System.out.println("While loop");
        List<String> nextLevelURLs = processURL(URLs.get(iterator
                .nextIndex()));
        for (String URL : nextLevelURLs) {
            if (!URLs.contains(URL)) {
                System.out.println(URL);
                iterator.add(new String(URL));
            }
        }
        System.out.println(URLs.size());
    }

    System.out.println("Total products found: " + productCount);
    System.out.println("Total searched page: " + searchedPageCount);
    System.out.println("Total skipped page: " + skippedPageCount);

    long t2 = System.currentTimeMillis();
    System.out.println("Total time taken: " + (t2 - t1) / 60000);
}

public static List<String> processURL(String URL) {

    List<String> nextLevelURLs = new ArrayList<String>();

    try {
        searchedPageCount++;
        // System.out.println("Current URL: " + URL);
        Elements products = Jsoup.connect(URL).timeout(60000).get()
                .select("div.product");

        for (Element product : products) {

            System.out.println(product.select(" a > h2").text());
            System.out.println(product.select(" a > h3").text());
            System.out.println(product.select(".product > a").attr("href"));
            System.out
                    .println(product.select(".image a > img").attr("src"));
            System.out.println(product.select(".price").text());
            System.out.println();

            productCount++;

        }

        // System.out.println("Total products found until now: " +
        // productCount);
        Elements links = Jsoup.connect(URL).timeout(60000).get()
                .select("a[href]");

        for (Element link : links) {
            URL = link.attr("href");
            if (URL.startsWith("http://www.example.com/")) {
                // System.out.println("URLs added.");
                nextLevelURLs.add(URL);
            } else {
                skippedPageCount++;
                // System.out.println("URL skipped: " + URL);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return nextLevelURLs;
}

}

3 个答案:

答案 0 :(得分:3)

不幸的是,没有办法同时启动两个线程。

让我解释一下:首先,序列thread1.Start();和thread2.Start();首先使用thread1执行,然后执行thread2。这意味着只有线程thread1在线程2之前被调度,而不是实际启动。这两种方法各占一小部分,因此人类观察者无法看到它们按顺序排列的事实。

更多,Java线程被安排,即。被指派最终被执行。即使你有一个多核CPU,你也不确定1)并行运行的线程(其他系统进程可能会干扰)和2)线程都在调用Start()方法之后启动。

但你可以用这种方式运行多个线程..

new Thread(thread1).start();
new Thread(thread2).start();

答案 1 :(得分:0)

基本上创建一个实现Runnable的类,在这段代码中放置处理一个url的代码。在每个URL的主类中,构造一个包含所需信息的类(例如URL),然后运行run

许多教授如何做多线程java的网站

答案 2 :(得分:0)

首先,您粘贴的代码看起来很糟糕,因为它定位的是一个简单的过程。您需要将其转换为OO形式,然后扩展Thread(或Runnable),例如:

public class URLProcessor extends Thread {
    private String url;
    public URLProcessor(String url) {
        this.url = url;
    }

    @Override
    public void run() {
       //your business logic to parse the site with "this.url" here
    }
}

然后使用主入口加载多个:

public static void main(String[] args) {
    List<String> allmyurls = null;//get multiple urls from somewhere
    for (String url : allmyurls) {
        URLProcessor p = new URLProcessor(url);
        p.start();
    }
}