java - 如何从 Swing Worker 运行服务执行器?

标签 java swing concurrency swingworker

我正在编写一个 IP 扫描器应用程序,这个过程需要很长时间,所以我在 gui 的后台使用的是服务执行器,如下所示:

 public static List<Future<String>> checkThisIP(String ipStart, String ipEnd) throws UnknownHostException {
    final ExecutorService es = Executors.newFixedThreadPool(10);
    final List<Future<String>> futures = new ArrayList<>();
    String ipStringStart;
    String ipStringEnd;
    String targetIpString;
    //my update
    ipStringStart = ipStart.substring(ipStart.lastIndexOf(".") + 1, ipStart.length());
    ipStringEnd = ipEnd.substring(ipEnd.lastIndexOf(".") + 1, ipEnd.length());
    targetIpString = ipStart.substring(0, ipStart.lastIndexOf(".") + 1);
    if (!ipStart.equals(ipEnd)) {
        for (int i = Integer.parseInt(ipStringStart); i <= Integer.parseInt(ipStringEnd); i++) {
            String currentIp = targetIpString + i;
            futures.add(runPingScan(es, currentIp));
        }
    } else {
        futures.add(runPingScan(es, ipStart));
    }
    es.shutdown();
    return futures;
}


public static Future<String> runPingScan(final ExecutorService es, final String ip) {
    return es.submit(new Callable<String>() {
        @Override
        public String call() {
            String returnMe = "";
           //custom ping class 
            Ping p = new Ping();
            //send message
            p.SendReply(ip);
            //IsReachable returns ture or false
            if(p.IsReachable()){
                returnMe=ip;
            }
            return returnMe;
           }

    });
}

这是使用 Jbutton 执行的原始延迟代码操作:

 // scan result is Future list returned from service executor 
    List<Future<String>> scanResult = p.checkThisIP(jFormattedTextField1.getText(), jFormattedTextField2.getText());
                    for (final Future<String> f : scanResult) {
                        try {
                            ip = f.get();
                            if (!ip.equals("")) {
                                arp ARP = new arp();
                                PortScan openPort = new PortScan();
                                IP ipClass = new IP();
                                mac = ARP.getMac(ip);
                                manufacturer = ARP.getOUI(mac);
                                ports = openPort.checkIpForPorts(ip);
                                hostname = ipClass.hostname(ip);
                                title = ipClass.htmlTitle(ip);
                                Object[] data = {ip, mac, manufacturer, ports, hostname, title};
                                tableModel.addRow(data);
                            }

                            if (jFormattedTextField1.getText().equals(jFormattedTextField2.getText()) && ip.equals("")) {
                                JOptionPane.showMessageDialog(null, "<html>Can not ping the address ! <br> Server might be protected by <b>WAF</b>.</html>", "Alert", HEIGHT);
                            }
                        } catch (Exception ex) {
                            Logger.getLogger(gui.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }

运行此代码很好,但是当我将其附加到开始扫描按钮时,GUI 滞后,我在谷歌上搜索并发现使用Swing Worker。当我单独实现 Swing Worker 时,它杀死了并发性,而当我实现两个 GUI 时,它仍然滞后。我的问题是无论如何都要让按钮(Swing 工作线程)调用服务执行器来执行其他进程?

最佳答案

我已经成功地通过实现 Swing Worker 来解决我的问题,并且函数在后台执行将为服务执行器启动一个新线程并防止延迟。

//The actionpreformed by the button
   SwingWorker worker = new SwingWorker<Void, Void>() {
            @Override
        // All actions are done this method
            protected Void doInBackground() throws Exception {
                String ip = "";
                String mac = "";
                String manufacturer = "";
                String ports = "";
                String hostname = "";
                String title = "";
                tableModel.setRowCount(0);
                PingScan p = new PingScan();
                List<Future<String>> scanResult = p.checkThisIP(jFormattedTextField1.getText(), jFormattedTextField2.getText());
                for (final Future<String> f : scanResult) {
                    try {
                        ip = f.get();
                        if (!ip.equals("")) {
                            arp ARP = new arp();
                            PortScan openPort = new PortScan();
                            IP ipClass = new IP();
                            mac = ARP.getMac(ip);
                            manufacturer = ARP.getOUI(mac);
                            ports = openPort.checkIpForPorts(ip);
                            hostname = ipClass.hostname(ip);
                            title = ipClass.htmlTitle(ip);
                            Object[] data = {ip, mac, manufacturer, ports, hostname, title};
                            tableModel.addRow(data);
                        }
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                }
                return null;
            }
        };
     worker.execute();

关于java - 如何从 Swing Worker 运行服务执行器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42228574/

相关文章:

java - 如何在 n 秒后停止 Swing 计时器?

Java 并发 - 为什么同步 setter(而不是 getter)不能使类线程安全?

python - master/worker 是否可扩展?

java - 如何在 JUnit 测试中验证复杂的 JSONObjects?

java - azure api 应用程序 (tomcat) 通过 kudu 编辑 server.xml

java - 增加 Gridlayout 中的行大小

java - Looper、工作线程等并发问题

当自定义按钮更改文本时,Java 布局不会更新组件大小

java - 对 java.sql.Time 类型执行时间算术的最佳方法是什么?

java - JSP 的 JTable 替代品