I/O系列篇(二)伪异步I/O
2018-06-09 本文已影响31人
无量散人
一、模型说明
1、伪异步I/O模型的模型图
image.png2、相对于BIO的改进点
伪异步I/O模型采用线程池和队列技术,解决了BIO由于客户端请求量过大时,导致服务端资源耗尽和宕机的问题。因为伪异步线程模型,当有新的客户端接入的时候,将客户端的socket封装成一个Task(线程对象),投递给后端的线程池处理,线程池维护一个消息队列和N个活跃的线程,对消息队列中的任务进行处理,由于线程池可以设置大小和最大线程数,所以占用的资源是可控的,无论多少个客户端并发访问,都不会导致资源耗尽和宕机。
3、伪异步I/O的弊端
由于底层通信仍然采用的是同步阻塞模型,所以从根本上无法解决问题。通过对输入、输出流的API文档进行分析,了解到读和写仍然是同步阻塞的,阻塞的时间取决于对方线程的I/O处理速度和网络I/O传输速度。从本质上讲,我们无法保证生产环境的网络状况和对方的应用程序足够快,如果我们的应用程序严重依赖于对方的处理速度,那么可靠性就非常的差。
二、代码
1、服务端代码
public class TimeServer {
public static void main(String[] args) throws IOException {
int port = 8080;
ServerSocket server = null;
try {
server = new ServerSocket(port);
System.out.println("the time server is start in port : " + port);
Socket socket = null;
TimerServerHandlerExecutePool threadPool = new TimerServerHandlerExecutePool(50,10000);
while (true){
socket = server.accept();
threadPool.execute(new Thread(new TimeServerHandler(socket)));
}
}catch (Exception e){
e.printStackTrace();
}finally {
if (server!=null){
server.close();
server = null;
}
}
}
}
public class TimerServerHandlerExecutePool {
private ExecutorService executor;
public TimerServerHandlerExecutePool(int maxPoolSize, int queueSize){
executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
maxPoolSize,
120L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(queueSize));
}
public void execute(Runnable task){
executor.execute(task);
}
}
2、客户端代码
public class TimerClient {
public static void main(String[] args) {
int port = 8080;
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("what time is now ?");
System.out.println("the time client send msg succeed");
String responsStr = in.readLine();
System.out.println("the time server response --- " + responsStr);
}catch (Exception e){
e.printStackTrace();
}finally {
if (out!=null){
out.close();
out = null;
}
if (in!=null){
try {
in.close();
in = null;
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
socket = null;
}
}
}
}
三、运行结果
1、服务端
the time server is start in port : 8080
the time server receive msg : what time is now ?
2、客户端
the time client send msg succeed
the time server response --- now time is : 1528519169887