我正在用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 :(得分:2)
您在Thread.start()
课程中覆盖了MultiThrImpl
,这意味着每次调用T1.start()
时都会创建一个但未启动的线程。然后在start()
内创建另一个线程,您执行启动。这最终会导致资源耗尽,因为无法收集未启动的线程。
而不是扩展Thread
,而是让MultiThrImpl
实施Runnable
。该类包含许多不必要的东西(例如线程的名称,可以通过Thread
类设置)。
答案 1 :(得分:2)
将端口扫描任务包装到Runnable
而不是生成原始任务并将其提交给有界Executors.newFixedThreadPool(20)
是有意义的。这将确保您不会耗尽CPU / RAM并且还会大大简化您的代码。