java网络编程(一):java传统的阻塞IO以及多线程解决方案
来源:互联网 发布:散列算法md5破解 编辑:程序博客网 时间:2024/04/29 11:36
最近在看一些IO模型相关的东西,被同步IO、异步IO、阻塞IO、非阻塞IO概念弄的有点晕,后面再慢慢学习和领悟。我们以socket IO编程为例子,我用的是JDK1.7.0_80,测试工具用的是SocketTest。我们先学习下最简单、最原始的IO模型,在《Unix网络编程卷》中被称为:blocking IO。
SingleThreadBlockingIO是我们用java socket编程实现的blocking IO。
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.ServerSocket;import java.net.Socket;public class SingleThreadBlockingIO {public static void main(String[] args) throws Exception{ServerSocket serverSocket = new ServerSocket(8888);while (true) {// 阻塞直到有客户端连接上 Socket clientSocket = serverSocket.accept(); try { process(clientSocket); } catch(Exception e) { e.printStackTrace(); clientSocket.close(); } }}private static void process( Socket clientSocket) throws Exception{System.out.println("client socket连接:" + clientSocket.getRemoteSocketAddress()); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); while(true) { // 阻塞直到客户端发送数据 String readLine = in.readLine(); System.out.println("来自客户端的消息:" + readLine); if("end".equals(readLine)) { break; } else { out.write("welcome from server."); out.newLine(); out.flush(); } }}}
运行上面这段代码,用SocketTest做以下测试:
1.启动一个SocketTest进程,连接到上面的服务端socket。
2.可以观察到:服务端socket控制台打印出了下面的信息。
3.再启动一个SocketTest进程,连接服务端socket。SocketTest工具并没有提示我们不能连接。
4.发现服务端控制台,并没有打印出第二个SocketTest的连接信息。也就是时候,第二个SocketTest客户端在等待中。因为服务端socket已经被第一个SocketTest客户端占用,还没有释放,所以无法服务第二个客户端。
5.第一个SocketTest客户端发送消息,能够成功收到服务端的消息。
6.server端能够收到和处理客户端1的消息。
7.在第二个SocketTest客户端发送消息,可以看到并没有收到服务端的回复。
8.服务端控制台也没有打印客户端2的消息。
9.停掉第一个SocketTest客户端,可以看到服务端控制台输出结果如下。
通过上面的测试步骤,我们可以看到:这种传统的socket,一次只能服务一个客户端,别的客户端都必须排队等候,效率很差,不能用于高并发的场景。
为了解决这个问题,我们可以引入多线程,为每个socket客户端单独开辟一个线程。
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.ServerSocket;import java.net.Socket;public class MultithreadBlockingIO {public static void main(String[] args) throws Exception{ServerSocket serverSocket = new ServerSocket(8888);while (true) {final Socket clientSocket = serverSocket.accept();Thread t = new Thread(new Runnable() {@Overridepublic void run() {try {process(clientSocket);} catch (Exception e) {e.printStackTrace();}}});t.start(); }}private static void process( Socket clientSocket) throws Exception{ System.out.println("client socket连接:" + clientSocket.getRemoteSocketAddress()); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); while(true) { String readLine = in.readLine(); System.out.println("来自客户端的消息:" + readLine); if("end".equals(readLine)) { break; } else { out.write("welcome from server."); out.newLine(); out.flush(); } }}}
可以像测试SingleThreadBlockingIO一样进行测试,可以看到2个SocketTest客户端之间没有影响。也就是说服务能够同时服务多个客户端。
了解并发编程都知道:这种为每个客户端分配一个线程的方案,在高并发的场景下仍然不行。因为创建线程是要消耗系统资源的,不能无限制的创建线程,而且线程太多会导致频繁的上下文切换,这些都会影响性能。我们可以使用线程池,创建固定个数的线程,这样不会导致系统因创建太多线程而崩溃,不过如果线程池被沾满,那么后续的客户端socket还是需要排队。正是由于使用了这种blocking IO模型,导致无论怎么做,都不太好。后面我们会慢慢学习其他的IO模型。
- java网络编程(一):java传统的阻塞IO以及多线程解决方案
- JAVA网络编程(一):阻塞IO实现
- IO的阻塞与非阻塞、同步与异步以及Java网络IO交互方式
- IO的阻塞与非阻塞、同步与异步以及Java网络IO交互方式
- IO的阻塞与非阻塞、同步与异步以及Java网络IO交互方式
- IO的阻塞与非阻塞、同步与异步以及Java网络IO交互方式
- java网络编程之传统IO与伪异步IO(一)
- Java网络编程 - 同步阻塞IO模型
- Java的Socket网络编程以及多线程
- IO的阻塞与非阻塞、同步与异步以及Java网络IO交互方式(转)
- java socket多线程阻塞IO
- Java网络编程-IO多路复用(多线程)
- 黑马程序员-java网络编程以及IO流的应用
- Thrift java 基于阻塞IO的服务端多线程通信
- Java中的NIO非阻塞模式和传统的IO的阻塞模式在线程中的资源消耗
- Java -网络IO编程
- Java 网络IO编程
- 网络编程Socket的阻塞和非阻塞IO
- 对于背景图等过大图片的处理
- 【Java】【Flume】Flume-NG启动过程源码分析(二)
- Android5.0 新特性学习总结
- 调用命令行的函数
- android USB通讯开发
- java网络编程(一):java传统的阻塞IO以及多线程解决方案
- 使用spring容器时,服务器不能顺利启动信息: Initializing Spring root WebApplicationContext log4j:WARN No appenders cou
- 简历筛选标准
- 调用接口返回失败时的必要操作
- 数据库基本语句
- 多进程通讯
- cookie 和session 的区别详解
- 详解shape标签
- [资料下载] 如何将接收RSSI实验数据得到距离计算公式呢?