知识大全 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]

Java线程模型缺陷研究[5]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 Java线程模型缺陷研究[4]

Java线程模型缺陷研究[4]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 Java线程模型缺陷研究[3]

Java线程模型缺陷研究[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 Java线程模型缺陷研究[2]

Java线程模型缺陷研究[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 Java线程模型缺陷研究[1]

Java线程模型缺陷研究[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 Java线程模型缺陷研究[7]

Java线程模型缺陷研究[7]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 Java 线程/内存模型的缺陷和增强

Java线程/内存模型的缺陷和增强  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java在语言

知识大全 Java Socket多线程如何支持服务器模型

JavaSocket多线程如何支持服务器模型  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Ja

知识大全 Java多线程之ConcurrentHashMap深入分析

Java多线程之ConcurrentHashMap深入分析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一

知识大全 Java多线程之volatile深入分析

Java多线程之volatile深入分析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  vola