创建n个线程,一次激活最多5个线程,等待所有线程完成后再继续

问题描述 投票:0回答:1

我正在用Java构建一个带有Selenium和MVC设计模式的Web爬虫。我正在努力实现三件事:

  1. 根据存储搜索设置的数据库(sidb)的长度创建n个线程。
  2. 因为我的GUI中有一个带有数据的TablePanel,所以我需要在继续之前完成所有线程。否则我将丢失一些数据因为table.refresh()方法被提前调用。
  3. 由于超过5个Firefox窗口同时运行会使我的计算机运行速度太慢,我希望在任何给定时间最多运行5个线程。

以下代码解决了第一个问题,在某种程度上解决了第二个问题。我不得不制作一个令人讨厌的Thread.sleep()来防止它过早地在桌面上运行刷新。

public void runSearchItems() {
        for (int i = 0; i < sidb.getSize(); i++) {
            final int num = i;
            Thread tn = new Thread(new Runnable() {

                @Override
                public void run() {
                    if (sidb.getSearhItem().get(num).getFormevent().getDomainBox().equalsIgnoreCase("www.someURL.com") == true) {
                        String searchField = sidb.getSearhItem().get(num).getFormevent().getSearchField();
                        int searchCat = sidb.getSearhItem().get(num).getFormevent().getSearchCategory();
                        boolean defect = sidb.getSearhItem().get(num).getFormevent().isDefectCheck();
                        boolean region = sidb.getSearhItem().get(num).getFormevent().isRegionCheck();
                        String arrange = sidb.getSearhItem().get(num).getFormevent().getArrangeBy();
                        ArrayList<SiteData> ls = wb.searchWebSite(searchField, searchCat, defect, region, arrange);
                        for (int j = 0; j < ls.size(); j++) {
                            db.addSiteData(ls.get(j));
                        }
                    }
                }
            });
            tn.start();
            try {
                tn.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

这样做的正确方法是什么?

谢谢!

java multithreading swing selenium-webdriver java-threads
1个回答
0
投票

对代码的细微更改

public void runSearchItems() { 
    List<Thread> allThreads = new ArrayList<>();


        for (int i = 0; i < sidb.getSize(); i++) {
            final int num = i;
            Thread tn = new Thread(new Runnable() {

                @Override 
                public void run() { 
                    if (sidb.getSearhItem().get(num).getFormevent().getDomainBox().equalsIgnoreCase("www.someURL.com") == true) {
                        String searchField = sidb.getSearhItem().get(num).getFormevent().getSearchField();
                        int searchCat = sidb.getSearhItem().get(num).getFormevent().getSearchCategory();
                        boolean defect = sidb.getSearhItem().get(num).getFormevent().isDefectCheck();
                        boolean region = sidb.getSearhItem().get(num).getFormevent().isRegionCheck();
                        String arrange = sidb.getSearhItem().get(num).getFormevent().getArrangeBy();
                        ArrayList<SiteData> ls = wb.searchWebSite(searchField, searchCat, defect, region, arrange);
                        for (int j = 0; j < ls.size(); j++) {
                            db.addSiteData(ls.get(j));
                        } 
                    } 
                } 
            }); 


            allThreads.add(tn);
        } 



        for(Thread t:allThreads)
            t.start();


        for(Thread t:allThreads)
            try { 
                t.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block 
                e.printStackTrace();
            }


    } 

但是,你最好使用Thread Pool

https://howtodoinjava.com/java/multi-threading/java-thread-pool-executor-example/为例

© www.soinside.com 2019 - 2024. All rights reserved.