【NIO引入】传统的IO模型
来源:互联网 发布:企业网络防火墙 编辑:程序博客网 时间:2024/06/07 00:26
传统的BIO模型
服务端代码:
public class Server1 { public static void main(String[] args) { System.out.println("服务器启动..."); Socket client = null; BufferedReader in = null; PrintWriter pw = null; BufferedReader br = null; try { ServerSocket server = new ServerSocket(8080); while (true) { //阻塞等待 client = server.accept(); in = new BufferedReader(new InputStreamReader(client.getInputStream())); pw = new PrintWriter(client.getOutputStream()); br = new BufferedReader(new InputStreamReader(System.in)); String s = in.readLine(); System.out.println("客户端: " +s); pw.println(br.readLine()); pw.flush(); if("end".equals(s)){ System.out.println("服务器将关闭连接"); break; } } } catch (IOException e) { e.printStackTrace(); }finally { try { br.close(); pw.close(); in.close(); client.close(); } catch (IOException e) { e.printStackTrace(); } } }}
客户端代码:
public class Client1 { public static void main(String[] args) { System.out.println("客户端1启动..."); System.out.println("当输入 \" end \" 时, 客户端将终止\n"); Socket server = null; Socket client = null; BufferedReader in = null; PrintWriter pw = null; BufferedReader br = null; try { while (true) { server = new Socket(InetAddress.getLocalHost(), 8080); br = new BufferedReader(new InputStreamReader(System.in)); pw = new PrintWriter(server.getOutputStream()); in = new BufferedReader(new InputStreamReader(server.getInputStream())); String str = br.readLine(); pw.println(str); pw.flush(); if("end".equals(str)){ System.out.println("客户端将关闭连接"); break; } System.out.println("服务器: "+in.readLine()); } }catch (IOException e) { e.printStackTrace(); }finally { try { in.close(); pw.close(); br.close(); server.close(); } catch (IOException e) { e.printStackTrace(); } } }}
分析:采用BIO通信模型的服务端。通常由一个独立的Acceptor线程负责监听客户端的连接,它接收到客户端的连接请求后为每一个客户端创建一个新的线程,处理完成后销毁线程,这是典型的一对一模型。
缺点:当客户端并发访问量增加后,服务端不得不创建多个线程,但线程是Java虚拟机非常宝贵的资源,系统会发生堆栈溢出、创建新线程失败等问题。
解决方法:创建一个线程池来存放新建的客户端连接(即伪异步模型)。
伪异步IO模型
服务端代码:
public class Server2 { public static void main(String[] args) throws IOException { ServerSocket server = null; try { server = new ServerSocket(8080); System.out.println("服务端启动...... "); Socket socket = null; TimeServerHandlerExecutePool singleExecutor = new TimeServerHandlerExecutePool( 50, 10000);// 创建IO任务线程池 while (true) { socket = server.accept(); singleExecutor.execute(new TimeServerHandler(socket)); } } finally { if (server != null) { server.close(); server = null; } } }}class TimeServerHandlerExecutePool { private ExecutorService executor; public TimeServerHandlerExecutePool(int maxPoolSize, int queueSize) { executor = new ThreadPoolExecutor(Runtime.getRuntime() .availableProcessors(), maxPoolSize, 120L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(queueSize)); } public void execute(java.lang.Runnable task) { executor.execute(task); }}class TimeServerHandler implements Runnable { private Socket socket; public TimeServerHandler(Socket socket) { this.socket = socket; } @Override public void run() { BufferedReader br = null; PrintWriter pw = null; try { br = new BufferedReader(new InputStreamReader( this.socket.getInputStream())); pw = new PrintWriter(socket.getOutputStream()); br = new BufferedReader(new InputStreamReader(System.in)); String s = br.readLine(); System.out.println("客户端: " +s); pw.println(br.readLine()); pw.flush(); } catch (Exception e) { if (br != null) { try { br.close(); } catch (IOException e1) { e1.printStackTrace(); } } if (pw != null) { pw.close(); pw = null; } if (this.socket != null) { try { this.socket.close(); } catch (IOException e1) { e1.printStackTrace(); } this.socket = null; } } }}
客户端代码不变(同BIO)
分析:伪异步IO虽然采用了线程池,避免了一请求一连接的问题,但它的底层还是采用同步阻塞模型,其最本质的问题在于,严重依赖于线程。但线程是很”贵”的资源
,因为线程的创建和销毁成本很高。
缺点:
由于线程池采用阻塞队列实现。当队列积满后,后续队列的操作将被阻塞。
线程的切换成本高的。
总结:
当面对十万甚至百万级连接的时候,传统的BIO模型是无能为力的。这就需要一种更高效的I/O处理模型。
本人才疏学浅,若有错误,请指出
谢谢!
阅读全文
0 0
- 【NIO引入】传统的IO模型
- 传统的IO模型
- NIO与传统IO的区别
- NIO与传统IO的区别
- NIO与传统IO的区别(概述)
- NIO与传统IO的区别
- NIO与传统IO的区别
- NIO与传统IO的区别
- NIO与传统IO的区别
- NIO与传统IO的区别
- 传统IO与NIO的比较
- NIO与传统IO的区别
- NIO与传统IO的区别
- NIO与传统IO的区别
- NIO与传统IO的区别
- NIO与传统IO的区别
- NIO与传统IO的区别
- NIO与传统IO的区别
- SQL Server导入超大SQL文件的方法
- Hibernate写实体映射方法
- 各种分布式文件系统简介
- Kotlin for Android
- ECMAScript 6 阅读笔记
- 【NIO引入】传统的IO模型
- pyhotn3入门基础-9迭代
- Avast高级版的cleanup激活码
- Windows8/8.1/10安装.NET Framework 3.5
- 求next数组nextval值
- coturn(turn/stun)服务器搭建
- vmware虚拟机CentOS利用vmware-tools工具如何与windows文件夹共享
- Windows下搭建Django开发环境
- Eclipse快捷键归纳及整理