知识大全 Java语言深入 多线程程序模型研究
Posted 知
篇首语:缥帙各舒散,前后互相逾。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Java语言深入 多线程程序模型研究相关的知识,希望对你有一定的参考价值。
Java语言深入 多线程程序模型研究 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
多线程是较复杂程序设计过程中不可缺少的一部分 为了提高应用程序运行的性能 采用多线程的设计是一种比较可行的方案 本文通过介绍使用Java编写的扫描计算机端口的实例 来说明多线程设计中应注意的问题 以及得出经常使用的多线程模型 本文要求读者具备一定的Java语言基础 对Socket有一定的了解 本文的所有程序在Java SDK 编译通过并能正常运行 现在 我们需要对一台主机扫描其端口 找出哪些端口是open的状态 我们先采用单线程进行处理 程序代码如下 import java io IOException;import Socket;import UnknownHostException;public class PortScannerSingleThread public static void main(String[] args) String host = null; //第一个参数 目标主机 int beginport = ; //第二个参数 开始端口 int endport = ; //第三个参数 结束端口 try host = args[ ]; beginport = Integer parseInt(args[ ]); endport = Integer parseInt(args[ ]); if(beginport <= || endport >= || beginport > endport) throw new Exception( Port is illegal ); catch(Exception e) System out println( Usage: java PortScannerSingleThread host beginport endport ); System exit( ); 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) 在以上程序中 通过 Socket类来识别端口是否是open状态 程序接受 个参数 第一个参数是主机IP 第二和第三个参数是需要扫描的起始和中止的端口号( ~ ) 本程序(java PortScannerSingleThread )运行结果如下 The port is opened at The port is opened at The port is opened at 但是 以上程序运行效率实在不敢恭维 把目标主机端口扫描一遍需要十几分钟甚至更长 估计没有哪个用户可以忍受这样的效率 所以 提高程序处理效率是必须的 下面的程序通过多线程的方法来进行处理 程序代码如下 import java io IOException;import Socket;import UnknownHostException;public class PortScannerMultiThread public static void main(String[] args) String host = null; int beginport = ; int endport = ; try host = args[ ]; beginport = Integer parseInt(args[ ]); endport = Integer parseInt(args[ ]); if(beginport <= || endport >= || beginport > endport) throw new Exception( Port is illegal ); catch(Exception e) System out println( Usage: java PortScannerSingleThread host beginport endport ); System exit( ); 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 )运行结果如下 The port is opened at The port is opened at The port is opened at 仔细对第 个程序分析 不难发现其中的问题 创建的线程个数是不固定的 取决于输入的第二和第三个参数 如果扫描 ~ 端口 那么主线程就产生 个线程来分别处理 如果扫描 ~ 端口 主线程就会产生 个线程来进行处理 在JVM中创建如此多的线程同样会带来性能上的问题 因为线程的创建和消失都是需要花费系统资源的 所以以上的第二个程序也存在明显的不足 所以 我们需要一个确定数量的线程在JVM中运行 这样就需要了解 线程池 (ThreadPool)的概念 线程池在多线程程序设计中是比不可少的 而且初学者不太容易掌握 下面通过对线程池的介绍 结合第 和第 个程序 引出两种常用的线程池模型 第一种实现线程池的方法是 创建一个 池 在 池 中增加要处理的数据对象 然后创建一定数量的线程 这些线程对 池 中的对象进行处理 当 池 是空的时候 每个线程处于等待状态 当往 池 里添加一个对象 通知所有等待的线程来处理(当然一个对象只能有一个线程来处理) 第二种方法是 同样创建一个 池 但是在 池 中放的不是数据对象 而是线程 可以把 池 中的一个个线程比喻成一个个 工人 当没有任务的时候 工人 们严阵以待 当给 池 添加一个任务后 工人 就开始处理并直到处理完成 在第 个程序中 定义了List类型的entries作为 池 这个 池 用来保存需要扫描的端口 List中的元素必须是Object类型 不能用基本数据类型int往池里添加 而需要用使用Integer 在processMethod()方法中 首先就启动一定数量的PortThread线程 同时在while循环中通过entries add( new Integer(port))往 池 里添加对象 在PortThread类的run()方法中通过entry = (Integer)entries remove(entries size() );取得 池 中的对象 转换成int后传递给Socket构造方法 第 个程序如下 import java io IOException;import InetAddress;import Socket;import UnknownHostException;import java util Collections;import java util LinkedList;import java util List;public class PortScanner private List entries = Collections synchronizedList(new LinkedList()); //这个 池 比较特别 int numofthreads; static int port; int beginport; int endport; InetAddress remote = null; public boolean isFinished() if(port >= endport) return true; else return false; PortScanner(InetAddress addr int beginport int endport int numofthreads) this remote = addr; this beginport = beginport; this endport = endport; this numofthreads = numofthreads; public void processMethod() for(int i = ; i < numofthreads; i++) //创建一定数量的线程并运行 Thread t = new PortThread(remote entries this); t start(); port = beginport; while(true) if(entries size() > numofthreads) try Thread sleep( ); // 池 中的内容太多的话就sleep catch(InterruptedException ex) continue; synchronized(entries) if(port > endport) break; entries add( new Integer(port)); //往 池 里添加对象 需要使用int对应的Integer类 entries notifyAll(); port++; public static void main(String[] args) String host = null; int beginport = ; int endport = ; int nThreads = ; try host = args[ ]; beginport = Integer parseInt(args[ ]); endport = Integer parseInt(args[ ]); nThreads = Integer parseInt(args[ ]); if(beginport <= || endport >= || beginport > endport) throw new Exception( Port is illegal ); catch(Exception e) System out println( Usage: java PortScannerSingleThread host beginport endport nThreads ); System exit( ); try PortScanner scanner = new PortScanner(InetAddress getByName(host) beginport endport nThreads); scanner processMethod(); catch(UnknownHostException ex) class PortThread extends Thread private InetAddress remote; private List entries; PortScanner scanner; PortThread(InetAddress add List entries PortScanner scanner) this remote = add; this entries = entries; this scanner = scanner; public void run() Integer entry; while(true) synchronized(entries) while(entries size() == ) if(scanner isFinished()) return; try entries wait(); // 池 里没内容就只能等了 catch(InterruptedException ex) entry = (Integer)entries remove(entries size() ); //把 池 里的东西拿出来进行处理 Socket s = null; try s = new Socket(remote entry intValue()); System out println( The port of + entry toString() + of the remote + remote + is opened ); catch(IOException e) finally try if(s != null) s close(); catch(IOException e)
以上程序需要 个参数 输入java PortScanner 运行(第 个参数是线程数) 结果前两个程序一样 但是速度比第一个要快 可能比第二个要慢一些 第 个程序是把端口作为 池 中的对象 下面我们看第 个实现方式 把 池 里面的对象定义成是线程类 把具体的任务定义成 池 中线程类的参数 第 个程序有 个文件组成 分别是ThreadPool java和PortScannerByThreadPool java ThreadPool java文件内容如下 import java util LinkedList;public class ThreadPool private final int nThreads; private final PoolWorker[] threads; private final LinkedList queue; public ThreadPool(int nThreads) this nThreads = nThreads; queue = new LinkedList(); threads = new PoolWorker[nThreads]; for (int i= ; i<nThreads; i++) threads[i] = new PoolWorker(); threads[i] start(); public void execute(Runnable r) synchronized(queue) queue addLast(r); queue notifyAll(); private class PoolWorker extends Thread public void run() Runnable r; while (true) synchronized(queue) while (queue isEmpty()) try queue wait(); catch (InterruptedException ignored) r = (Runnable) queue removeFirst(); try r run(); catch (RuntimeException e) 在ThreadPool java文件中定义了 个类 ThreadPool和PoolWorker ThreadPool类中的nThreads变量表示线程数 PoolWorker数组类型的threads变量表示线程池中的 工人 这些 工人 的工作就是一直循环处理通过queue addLast(r)加入到 池 中的任务 PortScannerByThreadPool java文件内容如下 import java io IOException;import InetAddress;import Socket;public class PortScannerByThreadPool public static void main(String[] args) String host = null; int beginport = ; int endport = ; int nThreads = ; try host = args[ ]; beginport = Integer parseInt(args[ ]); endport = Integer parseInt(args[ ]); nThreads = Integer parseInt(args[ ]); if(beginport <= || endport >= || beginport > endport) throw new Exception( Port is illegal ); catch(Exception e) System out println( Usage: java PortScannerSingleThread host beginport endport nThreads ); System exit( ); ThreadPool tp = new ThreadPool(nThreads); for(int i = beginport; i <= endport; i++) Scanner ps = new Scanner(host i); tp execute(ps);
cha138/Article/program/Java/gj/201311/27410相关参考
Java线程模型缺陷研究[5] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  
Java线程模型缺陷研究[4] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  
Java线程模型缺陷研究[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  
Java线程模型缺陷研究[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  
Java线程模型缺陷研究[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  
Java线程模型缺陷研究[7] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  
Java线程/内存模型的缺陷和增强 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Java在语言
JavaSocket多线程如何支持服务器模型 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Ja
知识大全 Java多线程之ConcurrentHashMap深入分析
Java多线程之ConcurrentHashMap深入分析 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一
Java多线程之volatile深入分析 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! vola