2017-07-13 18 views
-2

私はマルチスレッドポートスキャナプログラムをJavaで作成しています。コードは次のとおりです。マルチスレッドプログラムが崩壊する

final class MultiThrImpl extends Thread { 
    private Thread t; 
    final private String threadName; 
    final private String host; 
    final private int port; 

    MultiThrImpl(String name, String host, int port) { 
     this.threadName = name; 
     // Initialize the host and port to scan 
     this.host = host; 
     this.port = port; 
     // System.out.println("Creating " + threadName); 
    } 

    public void run() { 

     System.out.println("Running " + threadName); 
     String text; 
      try { 
       Socket socket = new Socket(host, port); 
       text = host + " is listening on port " + port; 
       System.out.println(text); 
       socket.close(); 
      } catch (UnknownHostException e) { 
       System.out.println("The IP address of the host " + "could not be determined"); 
       System.exit(1); 
      } catch (SecurityException e) { 
       System.out.println(
         "A security manager exists " + "and its checkConnect method doesn't allow the operation."); 
       System.exit(1); 
      } catch (IllegalArgumentException e) { 
       System.out.println("The port parameter is outside the specified range of valid port values, " 
         + "which is between 0 and 65535, inclusive"); 
       System.exit(1); 
      } catch (IOException e) { 
       // Every time a port that is closed is found an IO Exception is thrown 
       // Commented out so not to pollute the console output 
       /* 
       * System.out.println("An IO exception has occured"); 
       * System.exit(1); 
       */ 
      } 
      System.out.println("Terminating " + threadName); 
     } 

    public void start() { 
     //System.out.println("Starting " + threadName); 
     if (t == null) { 
      t = new Thread(this, threadName); 
      t.start(); 
     } 
    } 
} 

final public class Main { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     String host; 
     String text; 
     final int secToSleep = 2; 
     final int maxNumofThr = 10; 
     // if not exactly one host is not given 
     if (args.length != 1) { 
      System.out.println("Please give the name of the host to scan as " + "a parameter to the program"); 
      System.exit(1); 
     } 

     host = args[0]; 
     MultiThrImpl T1; 
     int port = 0; 
     int numOfThreads = 0; 
     // loop for all ports 
     while (port < 65535) { 

      T1 = new MultiThrImpl("Thread " + port, host, port); 
      T1.start(); 

      numOfThreads++; 
      // Do not let the program make more than maxNumofThr threads 
      if (numOfThreads >= maxNumofThr) { 
       System.out.println("Reached " + numOfThreads + " pausing"); 
       while (true) { 
        // Check that the last created thread has terminated 
        if (!T1.isAlive()) { 
         numOfThreads = 0; 
         System.out.println("About to continue execution"); 
         break; 
        } 
        // sleep for 2 seconds 
        try { 
         TimeUnit.SECONDS.sleep(secToSleep); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         System.out.println("Interrupted while sleeping - Terminating to debug"); 
         System.exit(1); 
        } 
       } 
      } 
      port++; 
     } 
    } 
} 

時間が経過してもプログラムが正常に起動する間、IDE全体が崩壊します。ガベージコレクタはオブジェクトを十分に高速に収集することはできません。問題の私の理解は正しいですか?もしそうなら、私はこれと戦うために何をすることができますか?

+0

'Thread.start()'を独自の実装でオーバーライドしましたか? – Kayaman

+0

@Kayaman私は[ここ](https://www.tutorialspoint.com/java/java_multithreading.htm)から元のアイデアを得ました –

+0

「IDE全体が崩壊する」とはどういう意味ですか? Eclipseは別のJVMでプログラムを実行するため、Eclipseのメモリには影響しません。 –

答えて

2

MultiThrImplクラスのThread.start()をオーバーライドしています。つまり、T1.start()に電話するたびにスレッドが作成されますが、開始されません。次にstart()の中に別のスレッドを作成します。となります。これにより、起動していないスレッドを収集できないため、最終的にリソースが不足します。

Threadの代わりにMultiThrImplRunnableを実装してください。クラスには不要なものがたくさん含まれています(スレッドの名前など、すでにThreadクラスで設定可能)。

2

未処理のタスクを生成して境界のあるExecutors.newFixedThreadPool(20)に送信するのではなく、ポートスキャンタスクをRunnableにラップすることは理にかなっています。これはあなたがCPU/RAMを使い果たしていないことを保証し、あなたのコードをかなり単純化します。