java - 在 public void method() 内的 for 循环中创建新线程

标签 java multithreading thread-safety ping void

我有一个可以 ping IP 地址的类。要开始 ping,我有公共(public) vod run() 方法来开始 ping。问题是我想同时 ping 更多的 IP 地址(对于每个 IP 地址我需要新的线程)。那么如何在 for 循环内创建新线程。这是我的 ping 类的代码:

public void run()
    {
    if (dbConnection.ConnectToDB())
    {           
        for (;GateWayKey<=GateWayKeyStop;GateWayKey++)
        {
            if(stop || this.isInterrupted()){
                return;
            }
            ip="192.168."+GateWayKey+".1";
            InetAddress address;
            try {
                address = InetAddress.getByName(ip);
                try {

                    if (address.isReachable(PingTime))
                    {

                        //System.out.println("Pronaden GateWay: "+ip)
                    //  labele.IP
                        sql="INSERT INTO `iptables` (`IP` , `COMPUTER_NAME` , `GATEWAY_KEY`) VALUES ('"+ip+"', '"+address.getHostName().toString()+"', '"+GateWayKey+"');";


                        framedocs.WriteMonitorData (ip, address.getHostName().toString(),"2000","DA",dbConnection.WriteToDB(sql));
                        for (;SubNetKey<=SubNetKeyStop;SubNetKey++)
                        {
                            if(stop || this.isInterrupted()){
                            return;
                            }
                            InetAddress addressIps = InetAddress.getByName("192.168."+GateWayKey+"."+SubNetKey);
                            System.out.println("Provjeravam IP: "+addressIps);
                            if (addressIps.isReachable(PingTime))
                            {
                                ip="192.168."+GateWayKey+"."+SubNetKey;
                                System.out.println("Pronaden IP: "+ip);
                                sql="INSERT INTO `iptables` (`IP` , `COMPUTER_NAME` , `GATEWAY_KEY`) VALUES ('"+ip+"', '"+addressIps.getHostName().toString()+"', '"+GateWayKey+"');";
                                framedocs.WriteMonitorData (ip, address.getHostName().toString(),"2000","DA",dbConnection.WriteToDB(sql));                          
                            }
                            else
                            {
                                framedocs.WriteMonitorData (addressIps.toString(), "N/A","2000","NE","N/A");
                            }

                        }
                    }
                    else
                    {
                            framedocs.WriteMonitorData (ip, "N/A","2000","NE","N/A");
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    framedocs.WriteMonitorData (ip, "N/A","2000",e.getMessage(),"N/A");
                }
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                ;
                framedocs.WriteMonitorData (ip, "N/A","2000",e.getMessage(),"N/A");
            }
        }

    }
    else
    {
        framedocs.WriteMonitorData ("MySQL error", "N/A","N/A","N/A","N/A");
    }

}

最佳答案

执行此类任务的一般方法是,首先创建一个类来保存您想要从每个线程获取的结果:

final class PingResult {
    public String ip;
    public String hostname;
    //... other things you want go here
}

然后创建一个执行实际工作的可调用对象

class PingTask extends Callable<PingResult>{
    private final String gateWayKey, subNetKey;
    //... other parameters you need go here
    public Ping( String gwKey, String snKey /*+ others? */ ){
        // This is just a way to pass parameters to your pinging function
        this.gateWayKey = gwKey;
        this.subNetKey = snKey;
        // ...
    }

    public PingResult call(){

        // Do actual pinging work here

        if ( /* Success */ )
        {
            PingResult result = new PingResult();
            result.ip= /*Fill these in*/;
            result.hostname = /* ... */;
            return result;
        }
        // Otherwise we failed, I'm using null as a failure sentinel
        // (you can come up with something better)
        return null;
    }
}

然后在调用代码中,设置线程池,提示请求,然后处理结果。

// Might need to tweak the # for best performance
final int NUM_THREADS = Runtime.getRuntime.availableProcesses(); 
ExecutorService exec = Executors.newFixedThreadPool( NUM_THREADS );

List<Future<PingResult>> results = new ArrayList<PingResult>();

for(/* ... */){
    results.add( exec.submit( new PingTask( gateway, subnet ) ) );
}

for( Future<PingResult> future : results ){
    PingResult result = future.get();

    // Process the result here (this is where you insert into the DB)
}

exec.shutdown(); // VERY IMPORTANT. If you don't do this the JVM will never stop.

关于java - 在 public void method() 内的 for 循环中创建新线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10177101/

相关文章:

java - Google Cal - 如何获取已完成/过去的事件

java - 尝试使用 WebService 从 Android 应用程序将数据插入 SQL Server

multithreading - 尝试创建多个线程时程序崩溃

Java:测试服务的并发性

c++ - 为什么使用原子 CAS 的程序不能保持线程安全?

java - 字符串应保持与 TextArea 类似的换行符

java - 使用 Java 打印 1-100 之间的完美数字

java - 分割字符串,记住分隔符并将其附加为空格

java - Apache Kafka - 关于主题/分区的 KafkaStream

C# 事件 : on which thread