|
Java语言深入:关于多线程程序模型研究 |
|
|
|
|
|
多线程是较复杂程序设计过程中不可缺少的一部分。为了提高应用程序运行的性能,采用多线程的设计是一种比较可行的方案。本文通过介绍使用Java编写的扫描计算机端口的实例,来说明多线程设计中应注重的问题,以及得出经常使用的多线程模型。
本文要求读者具备一定的Java语言基础,对Socket有一定的了解。本文的所有程序在Java SDK 1.4.2编译通过并能正常运行。
现在,我们需要对一台主机扫描其端口,找出哪些端口是open的状态。我们先采用单线程进行处理,程序代码如下: ------------------------------------------------------------------------------------------------------- import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException;
public class PortScannerSingleThread { public static void main(String[] args) { String host = null; //第一个参数,目标主机。 int beginport = 1; //第二个参数,开始端口。 int endport = 65535; //第三个参数,结束端口。 try{ host = args[0]; beginport = Integer.parseInt(args[1]); endport = Integer.parseInt(args[2]); if(beginport <= 0 || endport >= 65536 || beginport > endport){ throw new Exception("Port is illegal"); } }catch(Exception e){ System.out.println("Usage: java PortScannerSingleThread host beginport endport"); System.exit(0); }
for (int i = beginport; i <= endport; i ) { try { Socket s = new Socket(host, i); System.out.println("The port " i " is opened at " host); }catch (UnknownHostException ex) { System.err.println(ex); break; }catch (IOException ex) { } } } } -------------------------------------------------------------------------------------------------------- 在以上程序中,通过java.net.Socket类来识别端口是否是open状态。程序接受3个参数,第一个参数是主机IP,第二和第三个参数是需要扫描的起始和中止的端口号(1~65535)。本程序(java PortScannerSingleThread 10.1.1.1 1 1000)运行结果如下: The port 25 is opened at 10.1.1.182 The port 110 is opened at 10.1.1.182 The port 135 is opened at 10.1.1.182 ...
但是,以上程序运行效率实在不敢恭维,把目标主机端口扫描一遍需要十几分钟甚至更长,估计没有哪个用户可以忍受这样的效率。
所以,提高程序处理效率是必须的,下面的程序通过多线程的方法来进行处理。程序代码如下: ---------------------------------------------------------------------------------------------------------- import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException;
public class PortScannerMultiThread { public static void main(String[] args) { String host = null; int beginport = 1; int endport = 65535; try{ host = args[0]; beginport = Integer.parseInt(args[1]); endport = Integer.parseInt(args[2]); if(beginport <= 0 || endport >= 65536 || beginport > endport){ throw new Exception("Port is illegal"); } }catch(Exception e){ System.out.println("Usage: java PortScannerSingleThread host beginport endport"); System.exit(0); }
for (int i = beginport; i <= endport; i ) { PortProcessor pp = new PortProcessor(host,i); //一个端口创建一个线程 pp.start(); } } }
class PortProcessor extends Thread{ String host; int port; PortProcessor(String host, int port){ this.host = host; this.port = port; } public void run(){ try{ Socket s = new Socket(host,port); System.out.println("The port " port " is opened at " host); }catch(UnknownHostException ex){ System.err.println(ex); }catch(IOException ioe){ } } } ------------------------------------------------------------------------------------------------------------ 以上程序在for循环结构中创建PortProcessor对象,PortProcessor类是线程类,其要害的Socket在public void run()方法中实现。此程序比第一个单线程的程序运行效率提高很多倍,几乎在几秒钟内得出结果。所以可见多线程处理是何等的重要。 程序(java PortScannerMultiThread 10.1.1.100 1 1000)运行结果如下: The port 25 is opened at 10.1.1.100 The port 42 is opened at 10.1.1.100 The port 88 is opened at 10.1.1.100 ...
仔细对第2个程序分析,不难发现其中的问题:创建的线程个数是不固定的,取决于输入的第二和第三个参数。假如扫描1~100端口,那么主线程就产生100个线程来分别处理;假如扫描1~10000端口,主线程就会产生10000个线程来进行处理。在JVM中创建如此多的线程同样会带来性能上的问题,因为线程的创建和消失都是需要花费系统资源的。所以以上的第二个程序也存在明显的不足。
所以,我们需要一个确定数量的线程在JVM中运行,这样就需要了解“线程池”(ThreadPool)的概念。线程池在多线程程序设计中是比不可少的,而且初学者不太轻易把握,下面通过对线程池的介绍,结合第3和第4个程序,引出两种常用的线程池模型。
共4页: 上一页 1 [2] [3] [4] 下一页 |
上一篇:进阶-当前流行的J2EE WEB应用架构分析 下一篇:基于JDBC的数据库连接池技术研究与应用
|
相关文档 |
|
|
发表评论 |
|
|
|
|