为了解决同步阻塞I/O一个链路需要一个线程处理问题,对BIO模型做了优化——后端通过一个线程池处理多个客户端的请求接入,设置线程最大值,防止线程并发接入导致的线程耗尽。

当有新的客户端接入时,将客户端Socket封装成一个Task(该任务实现java.lang.Runnable接口)投递到后端的线程池中进行处理,JDK的线程池维护一个消息队列和N个活跃线程,对消息队列中的任务进行处理。由于线程池可以设置消息队列的大小和最大线程数,因此资源占用是可控的,无论多少客户端并发访问都不会导致资源耗尽和宕机。

伪异步I/O通信框架采用了线程池实现,避免了每次请求创建一个独立的线程造成的资源耗尽问题,底层通信依然采用BIO同步阻塞模型,无法从根本上解决问题。当对方发送请求或者应答消息比较缓慢(如数据大),或者网路传输较慢时(网速差)读取输入流一方的通信线程将被长时间阻塞,阻塞期间,其他接入消息只能在消息队列中排队。阻塞结束情况:1)有数据可读,2)可用数据已经读取完毕,3)发生空指针或IO异常

package com.hjp.netty.pseudoasynio;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; public 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(Runnable task) {
executor.execute(task);
} }

线程池处理类

package com.hjp.netty.pseudoasynio;

import sun.awt.windows.ThemeReader;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; public class TimeServer { public static void main(String[] args) throws IOException {
int port = 8080;
if (args != null && args.length > 0) {
try {
port = Integer.valueOf(port);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
ServerSocket server = null;
try {
server = new ServerSocket(port);
System.out.println("The time server is start in port : " + port);
Socket socket = null;
TimeServerHandlerExecutePool singleExecutor = new TimeServerHandlerExecutePool(50, 10000);
while (true) {
socket = server.accept();
singleExecutor.execute(new TimeServerHandler(socket));
}
} finally {
if (server != null) {
System.out.println("The time server close");
server.close();
server = null;
}
}
} }

TimeServer

package com.hjp.netty.pseudoasynio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Date; public class TimeServerHandler implements Runnable { private Socket socket; public TimeServerHandler(Socket socket) {
this.socket = socket;
} @Override
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("The time server receive order : " + body);
currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new Date(System.currentTimeMillis()).toString() : "BAD ORDER";
out.println(currentTime);
}
} catch (Exception e) {
if (in != null) {
try {
in.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (out != null) {
out.close();
out = null;
}
if (this.socket != null) {
try {
this.socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
this.socket = null;
}
}
}
}

TimeServerHandler

客户端代码和BIO客户端代码一样

Netty权威指南之伪异步I/O编程的更多相关文章

  1. Netty权威指南

    Netty权威指南(异步非阻塞通信领域的经典之作,国内首本深入剖析Netty的著作,全面系统讲解原理.实战和源码,带你完美进阶Netty工程师.) 李林锋 著   ISBN 978-7-121-233 ...

  2. 《Netty权威指南》

    <Netty权威指南> 基本信息 作者: 李林锋 出版社:电子工业出版社 ISBN:9787121233432 上架时间:2014-5-29 出版日期:2014 年6月 开本:16开 页码 ...

  3. 《Netty 权威指南(第2 版)》目录

    图书简介:<Netty 权威指南(第2 版)>是异步非阻塞通信领域的经典之作,基于最新版本的Netty 5.0 编写,是国内很难得一见的深入介绍Netty 原理和架构的书籍,也是作者多年实 ...

  4. Netty权威指南(笔记一)

    转载:http://blog.csdn.net/clarkkentyang/article/details/52529785 第一章(略) 第二章 NIO入门 2.1传统的BIO编程(同步阻塞I/O服 ...

  5. netty权威指南学习笔记一——NIO入门(2)伪异步IO

    在上一节我们介绍了四种IO相关编程的各个特点,并通过代码进行复习了传统的网络编程代码,伪异步主要是引用了线程池,对BIO中服务端进行了相应的改造优化,线程池的引入,使得我们在应对大量客户端请求的时候不 ...

  6. netty权威指南学习笔记六——编解码技术之MessagePack

    编解码技术主要应用在网络传输中,将对象比如BOJO进行编解码以利于网络中进行传输.平常我们也会将编解码说成是序列化/反序列化 定义:当进行远程跨进程服务调用时,需要把被传输的java对象编码为字节数组 ...

  7. netty权威指南学习笔记二——netty入门应用

    经过了前面的NIO基础知识准备,我们已经对NIO有了较大了解,现在就进入netty的实际应用中来看看吧.重点体会整个过程. 按照权威指南写程序的过程中,发现一些问题:当我们在定义handler继承Ch ...

  8. 《Netty权威指南》(二)NIO 入门

    [TOC]   2.1 同步阻塞 I/O 采用 BIO 通信模型的服务器,通常由一个独立的 Acceptor 线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行处理, ...

  9. netty权威指南学习笔记一——NIO入门(1)BIO

    公司的一些项目采用了netty框架,为了加速适应公司开发,本博主认真学习netty框架,前一段时间主要看了看书,发现编程这东西,不上手还是觉得差点什么,于是为了加深理解,深入学习,本博主还是决定多动手 ...

随机推荐

  1. Visual Studio 2008 调试运行Bug记录

    1.VS2008LINK : fatal error LNK1000: Internal error during IncrBuildImage (1). 打开要编译的项目(2). 在项目菜单中打开属 ...

  2. python 语法最佳实践

    1. 列表推倒 我们知道, 列表类似于数组, 列表里存储的都是对象, 所以列表中可以存储"数字","字符串" 等对象. 列表用中括号扩起, 然后逗号分隔 列表内 ...

  3. c:url标签

    <c:url>标签 <c:url>标签的主要作用是按照特定的重写规则重新构造URL,它的基本语法为: <c:url   value="原始URL"   ...

  4. 建议大家使用Java 8 的日期、时间,而非java.util.Date

    建议大家使用Java 8 的日期.时间,而非java.util.Date. 详细原因见:如何在Java 8中愉快地处理日期和时间 总结一下就是, java.util.Date 太乱,如 月份从0开始. ...

  5. e805. 监听JProgressBar的数值变化

    Whenever the value of a progress bar is changed, a change event is fired. In fact, the event is also ...

  6. Linux Shell nohup命令用法

    linux的nohup命令的用法.   在应用Unix/Linux时,我们一般想让某个程序在后台运行,于是我们将常会用 & 在程序结尾来让程序自动运行.比如我们要运行mysql在后台: /us ...

  7. 如何允许你的应用移动到SD卡?(转至http://blog.csdn.net/feng88724/article/details/6946670)

    我们在使用Android手机时发现,有的程序允许被移动到SD卡,而有的不行?这是为什么呢? 因为在Android 2.2版之后, Android应用才被允许移动到SD卡中.而在此之前开发的应用,全部没 ...

  8. Android Handler机制 (一个Thead中可以建立多个Hander,通过msg.target保证MessageQueue中的每个msg交由发送message的handler进行处理 ,但是 每个线程中最多只有一个Looper,肯定也就一个MessageQuque)

    转载自http://blog.csdn.net/stonecao/article/details/6417364 在android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长 ...

  9. vue input 赋值无效

    1.js代码如下 var vm = new Vue({ el:'#rrapp', data:{ q:{ name: null }, dict: {} }, }); 2.文本框代码如下 <inpu ...

  10. Solaris10 修改hostname

    修改/etc/nodename 及 /etc/hosts & /etc/hostname.<NIC Name> 这三个文件就可以了 重启