Netty入门到精通一(转)
因为一次工作需要,要从华为的一个区跑到另一个区开会,我终于见到了我心目中的大神(李林锋:Netty中国推广者,现华为技术有限公司平台中间件架构与设计部设计师),喜欢技术的我迫不及待的和他交流了起来,大神的技术果然牛逼,小弟膜拜中,大牛给我讲解了很多设计思想,在我遇到大部分开发者中,大多交流技术,用了什么什么技术,然后觉得很牛逼,经过和大牛交流后,才明白设计思想很重要,很多人注重用神马神马框架,神马神马技术,却不知道框架设计思想,为什么这么设计,这或许就是设计师和码农的区别吧(本人也只敢称自己是码农( >﹏<。),和大神交流后感觉自己弱爆了),一个好的产品是有设计思想和灵魂的,好吧这里我们就不扯蛋了。
好吧说说我为什么写下这篇文章吧,因工作需要,本人需要用到Netty,正好遇到了些问题,这是我就想起了大神,大神太忙了等了许久才回了我邮件(华为内部邮箱,华为内部不允许上网( >﹏<。) ),下班后在网上找了一些资料,发现大多要不不是很全,要不就很笼统,让人不好理解,看电子书很蛋疼吧,领导还安排有别的任务呢,再说相信对于初学者来说也遇到不少问题吧,然后自己资料整理了一下,写下此文章,本人会不定期的更新Netty文章,所以要有耐心一点,最好关注一下我的微博,当然心急吃不了热豆腐,有神马技术上的问题也可以一起交流,本人CSDN博客名Jimmy_zjf888,觉得写的不错的给个赞,送上鲜花,当然写的差的别吐槽丢大便就好。
首先我们要知道神马是Netty,我们为什么要用Netty,Netty的优势是神马?
Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性,那么NIO和传统IO有神马区别呢?下面我们来看看代码吧,这里的客户端和服务端我就用公司前台和参观客户做例子吧.
/**
* 传统socket服务端
* @author -Jimmy_zjf888-
*
*/
public class OrdinaryServer {
public static void main(String[] args)throws Exception {
//创建socket服务,打开并监听8888端口
ServerSocket server=new ServerSocket(8888);
while(true){
//获取一个套接字(阻塞)
final Socket socket = server.accept();
System.out.println("来个一个新客户!");
//前台妹子给客人端茶倒水
handler(socket);
}
}
/**
* 读取数据
* @param socket
* @throws Exception
*/
public static void handler(Socket socket){
try {
byte[] bytes = new byte[1024];
//获取socket的一个输入流
InputStream inputStream = socket.getInputStream();
while(true){
//循环读取读取数据(阻塞)
int read = inputStream.read(bytes);
if(read != -1){
System.out.println(new String(bytes, 0, read));
}else{
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我们运行一下如上代码,打开debug模式
哎哟一开始就发现final Socket socket = server.accept();代码执行到这一句的时候就开始阻塞了,这时我们用控制台的telnet去模拟吧
,然后回车,发现代码往下执行了,哎哟发现int read = inputStream.read(bytes);执行到这一句就阻塞了
总结了一下传统的IO有2个阻塞点一个系server.accept()的时候阻塞,另外一点系
nputStream.read(bytes)的时候阻塞,如果这么阻塞下去,如果有别的客人也来咱们公司参观的话,是不是那个前台妹子就不能照顾那个客人了?对没错的,我们再telnet一下试试
发现有新的客人来的时候我们的前台,只能照顾不周了,因为她在忙着照顾她第一个客人,那么我们该怎么办呢?是不是得多招几个前台妹子啊?听到这里有点小激动,又招妹子了,来看看怎么实现把,首先我们需要一个前台管理员,当客人来的时候能够负责分配空闲的前台去照顾客人对吧,代码如下。。。
public static void main(String[] args)throws Exception {
//创建一个线程池
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
//创建socket服务,打开并监听8888端口
ServerSocket server=new ServerSocket(8888);
while(true){
//获取一个套接字(阻塞)
final Socket socket = server.accept();
System.out.println("来个一个新客户!");
//派送空闲的前台妹子去接待客人
newCachedThreadPool.execute(new Runnable() {
@Override
public void run() {
//前台妹子给客人端茶倒水
handler(socket);
}
});
}
}
运行代码看看有没有像我们想象中的那样能够解决问题,
我们再来一次,看看问题还会不会存在
我们总结一下,单线程情况下只能有一个客户端,多线程的情况下可以有多个客户端,但非常消耗内存(要招很多前台妹子,公司的资源是有限的,不能不停招前台,虽然对咱们程序猿来说是福利,但对公司来说就是一笔不小的开资,那么我们应该怎么办呢?请看下篇)