zoukankan      html  css  js  c++  java
  • java scoket Blocking 阻塞IO socket通信二

    在上面一节中,服务端收到客户端的连接之后,都是new一个新的线程来处理客户端发送的请求,每次new 一个线程比较耗费系统资源,如果100万个客户端,我们就要创建100万个线程,相当的

    耗费系统的资源,服务器是没有办法支持这样多的客户端进行连接的

    我们可以采用线程池的方式来实现:提高

    package bhz.bio2;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class Client {
        
        final static String ADDRESS = "127.0.0.1";
        final static int PORT =8765;
        
        public static void main(String[] args) {
            Socket socket = null;
            BufferedReader in = null;
            PrintWriter out = null;
            try {
                socket = new Socket(ADDRESS, PORT);
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out = new PrintWriter(socket.getOutputStream(), true);
                
                out.println("Client request");
                
                String response = in.readLine();
                System.out.println("Client:" + response);
                
                
            }  catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if(in != null){
                    try {
                        in.close();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
                if(out != null){
                    try {
                        out.close();
                    } catch (Exception e2) {
                        e2.printStackTrace();
                    }
                }
                if(socket != null){
                    try {
                        socket.close();
                    } catch (Exception e3) {
                        e3.printStackTrace();
                    }
                }
                socket = null;                
            }
            
            
            
        }
    
    }
    package bhz.bio2;
    
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    public class HandlerExecutorPool {
    
        private ExecutorService executor;
        public HandlerExecutorPool(int maxPoolSize, int queueSize){
            this.executor = new ThreadPoolExecutor(
                    Runtime.getRuntime().availableProcessors(),
                    maxPoolSize, 
                    120L, 
                    TimeUnit.SECONDS,
                    new ArrayBlockingQueue<Runnable>(queueSize));
        }
        
        public void execute(Runnable task){
            this.executor.execute(task);
        }
        
        
        
    }
    package bhz.bio2;
    
    import java.io.BufferedReader;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class Server {
    
        final static int PORT = 8765;
    
        public static void main(String[] args) {
            ServerSocket server = null;
            BufferedReader in = null;
            PrintWriter out = null;
            try {
                server = new ServerSocket(PORT);
                System.out.println("server start");
                Socket socket = null;
                HandlerExecutorPool executorPool = new HandlerExecutorPool(50, 1000);
                while(true){
                    socket = server.accept();
                    executorPool.execute(new ServerHandler(socket));
                }
                
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(in != null){
                    try {
                        in.close();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
                if(out != null){
                    try {
                        out.close();
                    } catch (Exception e2) {
                        e2.printStackTrace();
                    }
                }
                if(server != null){
                    try {
                        server.close();
                    } catch (Exception e3) {
                        e3.printStackTrace();
                    }
                }
                server = null;                
            }
            
        
        
        }
        
        
    }
    package bhz.bio2;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
    
    public class ServerHandler implements Runnable {
    
        private Socket socket;
        public ServerHandler (Socket socket){
            this.socket = socket;
        }
        
        @Override
        public void run() {
            BufferedReader in = null;
            PrintWriter out = null;
            try {
                in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
                out = new PrintWriter(this.socket.getOutputStream(), true);
                String body = null;
                while(true){
                    body = in.readLine();
                    if(body == null) break;
                    System.out.println("Server:" + body);
                    out.println("Server response");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(in != null){
                    try {
                        in.close();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
                if(out != null){
                    try {
                        out.close();
                    } catch (Exception e2) {
                        e2.printStackTrace();
                    }
                }
                if(socket != null){
                    try {
                        socket.close();
                    } catch (Exception e3) {
                        e3.printStackTrace();
                    }
                }
                socket = null;            
            }
            
            
        }
    
    }

     阻塞模式:列如客户端请求服务器的数据,服务器如果返回10个字节的数据给客户端,如果网络较差,客户端就必须一致等待着指定10个字节发送完成,就一直阻塞着

    非阻塞模式nio模式:应用程序无需等待可以直接获得服务器端的数据,无效等待,线程不会阻塞

    阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
    非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

    同步和异步:

    A. 同步
    所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。

    按照这个定义,其实绝大多数函数都是同步调用(例如sin isdigit等)。
    但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。
    最常见的例子就是 SendMessage。
    该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回。
    当对方处理完毕以后,该函数才把消息处理函数所返回的值返回给调用者。


    B. 异步
    异步的概念和同步相对。
    当一个异步过程调用发出后,调用者不会立刻得到结果。
    实际处理这个调用的部件是在调用发出后,
    通过状态、通知来通知调用者,或通过回调函数处理这个调用。

    以 Socket为例,
    当一个客户端通过调用 Connect函数发出一个连接请求后,调用者线程不用等待结果,可立刻继续向下运行。
    当连接真正建立起来以后,socket底层会发送一个消息通知该对象。

    C. 三种返回结果途径 
    执行部件和调用者可以通过三种途径返回结果:
    a.   状态、
    b.   通知、
    c.   回调函数。

    总结:阻塞是针对当前的线程

    同步和异步:值得的函数的返回值,同步调用者会一直等待值得服务器返回值,异步是调用该函数不会立刻得到返回值,服务器通知、或者回调的方法通知调用者

    getInputStream和getOutputStream都是同步并且阻塞的模型

    jdk1.7版本之前nio是同步非阻塞的,在1.7以后实现了异步非阻塞的

  • 相关阅读:
    Spring Cloud的小改进(五)
    国内最火的10款Java开源项目,都是国人开发,CMS居多
    创建服务的注册与发现 Eureka (四)
    Eureka的的概述(三)
    sourcetree 跳过首次登录
    基于IDEA工具 lombok 的使用
    面试总结
    Spring Cloud的概述(二)
    微服务的概述(一)
    原子性 CAS算法
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/7661118.html
Copyright © 2011-2022 走看看