java之阻塞IO(BIO)

来源:互联网 发布:mac声音键不能调节 编辑:程序博客网 时间:2024/05/19 16:02

采用BIO通信模式的服务端,通常有一个独立的Acceptor线程负责监听客户端的连接,它接收到连接后,为每个客户端创建一个线程进行链路处理,处理完成后通过输出流,返回给客户端,线程销毁,这是典型的一对一应答通信模型。

该模型最大的问题就是缺乏弹性的伸缩能力,当客户端的并发访问增多时,服务端的线程个数与客户端的并发访问数呈1:1的正比关系,因此系统的性能将会急剧下降,并且随着并发访问量的继续增大,系统会发生线程堆栈溢出,创建新线程失败等问题。
服务端:
public class ServerDemo {private static final int PORT = 10000;public static void main(String[] args) {ServerSocket server = null;try { server = new ServerSocket(PORT); System.out.println("Server 监听端口:"+PORT); while(true){ Socket socket = server.accept(); new Thread(new ServerHandlerDemo(socket)).start(); }} catch (IOException e) {e.printStackTrace();}}}
public class ServerHandlerDemo implements Runnable {private Socket socket;public ServerHandlerDemo(Socket socket){this.socket = socket;}@Overridepublic void run() {BufferedReader reader = null;PrintWriter writer = null;try {reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));writer = new PrintWriter(socket.getOutputStream(),true);String line = null;while(true){line = reader.readLine();if(line == null){break;}if("QUERY CURRENT TIME".equals(line.trim())){DateFormat format = new SimpleDateFormat("yyyy-MM-dd");String nowDate = format.format(new Date());writer.println("The current time is "+nowDate);}else{writer.println("请求参数错误:"+line);}}} catch (IOException e) {e.printStackTrace();}finally{if(writer != null){writer.close();writer = null;}if(reader != null){try {reader.close();} catch (IOException e) {e.printStackTrace();}reader = null;}if(socket != null){try {socket.close();} catch (IOException e) {e.printStackTrace();}socket = null;}}}}
客户端:
public class ClientDemo {private static final String HOST = "localhost";private static final int PORT = 10000;public static void main(String[] args) {Socket client = null;BufferedReader reader = null;PrintWriter writer = null;try { client = new Socket(HOST,PORT); writer = new PrintWriter(client.getOutputStream(),true); writer.println("QUERY CURRENT TIME"); System.out.println("请求发送成功!!!!");  reader = new BufferedReader(new InputStreamReader(client.getInputStream())); String line = reader.readLine(); System.out.println(line);} catch (IOException e) {e.printStackTrace();}finally{if(reader != null){try {reader.close();} catch (IOException e) {e.printStackTrace();}reader = null;}if(writer != null){writer.close();writer = null;}if(client != null){try {client.close();} catch (IOException e) {e.printStackTrace();}client = null;}}}}
我们发现:BIO的主要问题在于每当有一个新的客户端接入时,服务器必须创建一个新的线程处理新接入的客户端链路,一个线程只能处理一个客户端连接。在高性能的服务器领域,往往需要成千上万个客户端并发连接,这种模型显然是无法满足高性能、高并发的场景的。
下面,我们对这个模型进行改进,通过线程池和消息队列实现一个或者多个线程处理N个客户端的模型,由于它的底层机制依然使用的是同步阻塞IO,所以我们这里称他为”伪异步IO“
了解”伪异步IO“,请看下一篇



原创粉丝点击