2016-08-13 17 views
1

次のコードは、/ 24 IP hostListに対する254回のping要求をそれぞれ独自のスレッドで実行します(またはこれは私の考えです)。 full/24サブネット(172.21.0.0/24)がhostListにロードされ、forループ内のワーカーに渡され、各スレッドがキックされてpingが完了します。Javaのicmp4jマルチスレッドpingがマルチスレッドではない

各pingスレッドのタイムアウトは1000msです。したがって、254個のIPが254個のスレッドに渡された場合、完全なプロセスは1〜2秒を超えてはなりません。

つまり、プログラムが本当にマルチスレッドの場合は、2秒未満でこの/ 24インチのすべてのIPにpingできるはずです。

結果は、各ホストが並列ではなく直列にpingされているようです...これを真のマルチスレッドpingアプリケーションにするという点で私は間違っていますか?

/* 
* Step 1: Ping a subnet to find alive hosts 
*/ 
package smartsdiscoveryrobot;  

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors;  

import org.icmp4j.IcmpPingUtil; 
import org.icmp4j.IcmpPingRequest; 
import org.icmp4j.IcmpPingResponse;  

import org.apache.commons.net.util.SubnetUtils; // Subnet Utils to genrate host list  

/** 
* 
* @author beukesmar 
*/ 
public class PingExecutorService {  

    private static final String COMMUNITY  = "public"; 
    private static final int NUMBEROFPINGS = 1; 
    private static final int PINGTIMEOUT  = 1000; 
    //Determine how many threads should be spawned by fetching the number of processors from Runtime 
    //private static final int NUM_THREADS  = Runtime.getRuntime().availableProcessors(); 
    private static final int NUM_THREADS  = 254; //Runtime.getRuntime().availableProcessors();  

    public static void main(String args[]) throws Exception { 
     System.out.println("Availabe threads: " + NUM_THREADS); 
     // Instantitate new Fixed size thread pool with NUM_THREADS 
     ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);  

     SubnetUtils utils = new SubnetUtils("172.21.0.1", "255.255.255.0"); 
     System.out.println("Low Address: " + utils.getInfo().getLowAddress()); 
     System.out.println("High Address: " + utils.getInfo().getHighAddress()); 
     // Construct hostList with all IP's in above subnet 
     String[] hostList = utils.getInfo().getAllAddresses();  

     // Create worker for each host in hostlist 
     System.out.println("Host array length: " + hostList.length); 
     for (String host : hostList) { 
      Runnable worker = new MyRunnable(host, PINGTIMEOUT, COMMUNITY); 
      executor.execute(worker); 
     } 
     executor.shutdown(); 
     // Wait until all threads are finish 
     while (!executor.isTerminated()) {  

     } 
     System.out.println("\nFinished all threads"); 
    }  

    public static class MyRunnable implements Runnable {  

     private final String host; 
     private final String community; 
     private final int pingtimeout;  

     MyRunnable(String host, int pingtimeout, String community) { 
      this.host = host; 
      this.pingtimeout = pingtimeout; 
      this.community = community; 
     }  

     @Override 
     public void run() { 
      System.out.print("Spawning new thread to ping to host: " + host + " timeout=" + pingtimeout + "\n");  

      /* 
      Code to perform ping 
      */ 
      final IcmpPingRequest request = IcmpPingUtil.createIcmpPingRequest(); 
      request.setHost(host); 
      request.setTimeout(pingtimeout); 
      request.setPacketSize(32); // Send 32 bytes  

      // Perform NUMBEROFPINGS pings per host 
      int numberofpings = NUMBEROFPINGS; 
      int numberofsuccesspings = 0; 
      int numberoffailedresponse = 0; 
      int minlatency = 0; 
      long avglatency = 0; 
      int maxlatency = 0; 
      int sumoflatency = 0; 
      long totaltime = 0; 
      boolean isalive = false; 
      boolean haspacketloss = false; 
      for (int i = 1; i <= numberofpings; i++) { 
       final IcmpPingResponse response = IcmpPingUtil.executePingRequest(request); 
       // host responded to a echo request 
       if (response.getSuccessFlag() == true) { 
        isalive = true; 
        numberofsuccesspings++; 
        //System.out.println("Reply from " + host + " icmp_req=" + i + " bytes=" + response.getSize() + " time=" + response.getRtt() + "ms"); 
        // Set inital values 
        if (minlatency == 0) { 
         minlatency = response.getRtt(); 
         maxlatency = response.getRtt(); 
        } 
        // Set minlatency if response latency is lower than minlatency 
        if (response.getRtt() < minlatency) { 
         minlatency = response.getRtt(); 
        } 
        // Set maxlatency if response latency is higher than maxlatency 
        if (response.getRtt() > maxlatency) { 
         maxlatency = response.getRtt(); 
        } 
        sumoflatency = sumoflatency + response.getRtt(); 
        totaltime = totaltime + response.getDuration(); 
        // host has dropped a echo request packet 
       } else { 
        haspacketloss = true; 
        numberoffailedresponse++; 
        //System.out.println("Reply from " + host + ":Error:" + response.getErrorMessage()); 
        totaltime = totaltime + response.getDuration(); 
       }  

       //final String formattedResponse = IcmpPingUtil.formatResponse(response); 
       //System.out.println(host + ":" + formattedResponse); 
      }  

      long packetloss = numberoffailedresponse/numberofpings * 100; 
      // Dont devide by 0 
      if (numberofsuccesspings != 0) { 
       avglatency = sumoflatency/numberofsuccesspings; 
      }  

      /*System.out.println(
        "---" + host + " ping statistics ---\n" 
        + numberofpings + " packets transmitted, " + numberofsuccesspings + ", " + packetloss + "% packet loss, time " + totaltime + "ms\n" 
        + "rtt min/avg/max = " + minlatency + "/" + avglatency + "/" + maxlatency + " ms");*/ 
      System.out.println(host + " isalive=" + isalive + " haspacketloss=" + haspacketloss); 
     } 
    } 
} 
+0

マシンに固定数のコアがあります。その数はおそらく1から16の間のどこかにあります(あなたが "コア"を数える方法に依存します)。おそらく4または8(再び、依存している)。これは、あなたのCPU上で実行できる本当に並行するものの最大数です。これらをインターリーブする場合は、非同期I/Oを実行する必要があります。 –

+0

@ T.J.Crowderは、システムコールでブロックされ、pingへの応答を待っているスレッドは、コアの数をカウントしません。スレッドは、マルチコアCPUよりもずっと長くなっています。人々がそれらを使用し始めた主な理由の1つは、別のスレッドを使用して異なるファイル/デバイス/ネットワークポートで同期I/O呼び出しを行うことが、非同期I/O呼び出しよりも理解しやすくなるからです。 –

+0

@ jameslarge:システムコールの場合はyesです。しかし、非同期I/Oがマルチスレッド同期I/Oより優れた性能を発揮する理由があります。 –

答えて

0

icmp4jは並列でpingできないようではありません。一度に1 pingします。

なぜ、野生の推測:jnaと何か関係があるかもしれません。

私の解決策は、processbuilderを使用してネイティブpingコマンドを実行することでした。