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

标签 java multithreading swing selenium-webdriver java-threads

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

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

正确的做法是什么?

谢谢!

最佳答案

对代码进行小改动

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


    } 

但是,是的,你更适合使用线程池

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

关于java - 创建 n 个线程,一次最多 5 个 Activity 线程,等待所有线程完成后再继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55778401/

相关文章:

java - 在JSP中通过PreparedStatement获取数据

c# - 如何处理任务并行库中的目录文件?

android - 使用线程等待来自服务的消息

java - 是否有任何解析器可以将 SQL 转换为树(AST)?

java - 静态字段无法在静态 block 中前向引用,但可以赋值

Java JNI : Creating a Swing Window using JNI from C

java - 运行后JFrame显示不正确

java - JOptionPane 图标在 Windows 10 中被裁剪

java - 为什么在 Java SWT Selection 监听器中新创建的元素无法显示/触发绘制事件?

Swift 线程 : When to use DispatchQueue. main.async?