多线程程序崩溃系统

时间:2017-07-13 13:16:10

标签: java eclipse multithreading

我正在用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都会崩溃。据我所知,垃圾收集器无法快速收集对象。我对问题的理解是否正确?如果是这样我该怎么做来对抗这个?

2 个答案:

答案 0 :(得分:2)

您在Thread.start()课程中覆盖了MultiThrImpl,这意味着每次调用T1.start()时都会创建一个但未启动的线程。然后在start()内创建另一个线程,您执行启动。这最终会导致资源耗尽,因为无法收集未启动的线程。

而不是扩展Thread,而是让MultiThrImpl实施Runnable。该类包含许多不必要的东西(例如线程的名称,可以通过Thread类设置)。

答案 1 :(得分:2)

将端口扫描任务包装到Runnable而不是生成原始任务并将其提交给有界Executors.newFixedThreadPool(20)是有意义的。这将确保您不会耗尽CPU / RAM并且还会大大简化您的代码。