同步阻塞通信-伪异步I/O编程

Posted Lance_xu_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了同步阻塞通信-伪异步I/O编程相关的知识,希望对你有一定的参考价值。

  1. 伪异步通信其底层实现还是同步通信,同步通信一请求一应答的特性让每一个客户端请求服务端都需要请起一个线程处理,在高并发的情况下极易容易导致系统资源耗尽而导致宕机等现象,伪异步是通过一个客户端线程池,让线程池中的一个线程处理多个客户端请求,高并发情况下系统线程资源消耗不会增加。
  2. 服务器实现
package com.haidong.forged_bio;

import com.haidong.bio.TimeServerHandler;

import java.net.ServerSocket;
import java.net.Socket;

/**
 * TimeServer
 *
 * @author Lance
 * @date 2017/05/31
 */
public class TimeServer 
    public static void main(String[] args) throws Exception 
        int port = 8080;
        if(args.length > 0 && args != null)
            try 
                port = Integer.valueOf(port);
             catch (NumberFormatException e) 
                //采用默认值
                e.printStackTrace();
            
        
        ServerSocket server = null;
        try 
            server = new ServerSocket(port);
            System.out.println("时间服务器开启:" + port);
            Socket socket = null;
            TimeServerHandlerExecutePool singleExecutor = new  TimeServerHandlerExecutePool(50, 10000);
            while (true)
                //监听
                socket = server.accept();
                singleExecutor.execute(new com.haidong.forged_bio.TimeServerHandler(socket));
            
         finally 
            if(server != null)
                System.out.println("关闭服务器");
                server.close();
                server = null;
            
        
    

3.线程池编码实现

package com.haidong.forged_bio;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * TimeServerHandlerExcutePool
 *
 * @author Lance
 * @date 2017/05/31
 */
public class TimeServerHandlerExecutePool 
    private ExecutorService executor;

    public TimeServerHandlerExecutePool(int maxPollSize, int queueSize)
        executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), maxPollSize, 120L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(queueSize));
    

    public void execute(Runnable task)
        executor.execute(task);
    

4.业务处理

package com.haidong.forged_bio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Date;

/**
 * TimeServerHandler
 *
 * @author Lance
 * @date 2017/05/31
 */
public class TimeServerHandler implements Runnable 
    private Socket socket;

    public TimeServerHandler(Socket socket) 
        this.socket = socket;
    

    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 currentTime = null;
            String body = null;
            while (true)
                //读取
                body = in.readLine();
                if (body == null)
                    break;
                
                System.out.println("服务器接收到客户端内容:" + body);
                currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new Date(System.currentTimeMillis()).toString() : "BAD ORDER";
                out.println(currentTime);
            
         catch (IOException e) 
            e.printStackTrace();
            if(in != null)
                try 
                    in.close();
                 catch (IOException e1) 
                    e1.printStackTrace();
                
                in = null;
            
            if(out != null)
                out.close();
                out = null;
            
            if(this.socket != null)
                try 
                    socket.close();
                 catch (IOException e1) 
                    e1.printStackTrace();
                
                socket = null;
            
        
    

5.客户端

package com.haidong.forged_bio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * TimeClient
 *
 * @author Lance
 * @date 2017/05/31
 */
public class TimeClient 
    public static void main(String[] args) 
        int port = 8080;
        if(args.length > 0 && args != null)
            try 
                port = Integer.valueOf(port);
             finally 
                //默认值
            
        
        Socket socket = null;
        BufferedReader in = null;
        PrintWriter out = null;
        try 
            socket = new Socket("127.0.0.1", port);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);
            out.println("QUERY TIME ORDER");
            System.out.println("查询时间success");
            String resp = in.readLine();
            System.out.println("当前时间" + resp);
         catch (IOException e) 
            e.printStackTrace();
         finally 
          if(out != null)
              out.close();
              out = null;
          
          if(in != null)
              try 
                  in.close();
               catch (IOException e) 
                  e.printStackTrace();
              
              in = null;
          
          if(socket != null)
              try 
                  socket.close();
               catch (IOException e) 
                  e.printStackTrace();
              
              socket = null;
          
        
    

6.运行服务端和客户端结果

以上是关于同步阻塞通信-伪异步I/O编程的主要内容,如果未能解决你的问题,请参考以下文章

java网络通信:伪异步I/O编程(PIO)

linux 网络编程 ---高级I/O

linux 网络编程 ---高级I/O

网络编程中常见的5种I/O模型

2017.07.12 Python网络编程之使用多路复用套接字I/O

I/O 怎样理解阻塞非阻塞与同步异步的区别?