Java socket网络编程(一) NIO与BIO

今天来讲讲java BIO与NIO的区别与socket网络编程,因为最近在做与之相关的项目有了不少的心得。
首先我来谈 BIO,BIO就是BlockingIO阻塞IO。什么是阻塞?阻塞就是程序运行到某处代码,不得不暂停等待一段时间,无事可干,等得到了结果才技能继续运行,常见的比如说我们用程序运行Mybatis执行一个查询语句,再获得查询结果之前,我们程序是卡在那里的。这个就是阻塞。有的阻塞是必不可少的,但是有的阻塞是可以避免的。阻塞的缺点是一个线程在被阻塞以后做不了其他事,一个线程执行会消耗很长的时间,那么为了能在一定的时间内做更多的事,人们发明了多线程,多用几个线程来做事,这样虽然提高了产出,但是单个线程的效率并没有得到提高,实现多线程的代价就是需要消耗更多的cpu和内存。
打比方你需要做三件事,烧水1壶水,煮1电饭煲的饭,烧1个菜。在半个小时内完成。
方法1是让一个人先烧水,水没烧开之前一直阻塞在那一动不动,烧完水了,再煮饭,饭没熟之前又阻塞了动不了,饭煮熟了再做菜,直到菜做完。这个就是BIO的做法。这么一看半个小时之内很难完成任务了,于是又改进了方法1成为方法2。方法2的做法是叫3个人,每个人只做一件事,这三个人都阻塞在他们自己的那件事上。这就是BIO的多线程做法。这种做法还是效率低下,很浪费人力。方法3是一个人把水烧上,不等水开,先去煲饭,不等饭熟去炒菜。让三件事同时运行。效率提高了!这个就是NIO的做法。

BIOsocket编程的阻塞体现在哪些地方呢? 我们回忆一下BIO TCP编程的写法,首先实例化一个serversocket监听一个端口,然后serverSocket.accept()方法会阻塞住,等待别人连接,别人不连接就一直阻塞在这里,等来了一个连接这个方法会生成一个socket 这个socket调用read方法读取socket里面的inputsream,这个read()又是阻塞的,如果这个socket的另一头不发送数据过来,程序就会一直卡在read()方法上,等待别人传数据。这里的等待别人连接和等待别人发数据就像烧水和煮饭,除了装水,装饭,一点完火以后我们什么也做不了,只能傻等。如果有100个人想要连接过来,我们这么阻塞住一个一个解决,那么最后一个连接在发起连接的请求后得过多久才能真正连接得上呢?后来用多线程解决了一部分问题。但是效率还是不是很高,因为单个线程得效率并没有提高多少。只是用线程得数量弥补产出能力低下。
我们接下来说NIO Non-blockingIO非阻塞IO, BIO有个叫selector得东西,selector得作用是相当于是一个“观察者与提醒者", 什么意思?在前面烧水,煮饭,炒菜的例子中我们没有注意到的一个细节时,我们用最后一个方法在同时做三件事的时候其实还需要时刻观察这三件事的进度,也就是水开了没,饭熟了没,菜炒好了没,如果没有观察,那么水开了没人去处理。当然我们也不需要时刻观察,我们只需要在水壶上装一个响铃,水一开就响,我们就可以去解决。selector就是这么个作用。 NIO用socketchannel监听一个端口,然后将socketchannel挂在一个interest为 acceptable的selector上, 这个selector的兴趣是观察挂在它身上的socketchannel有没有变成acceptable可连接状态的,也就是一旦这个socketchannel有人连接(此时socketchannel是acceptable),selector就会提醒我, 我就赶快派人处理拿出此时为acceptable状态的(一个或多个)socketchannel,这时如果是BIO就会对这些socketchannel进行read()阻塞住等待另一头传数据(阻塞),NIO不这么做,NIO再将这个acceptable状态的sockechannel挂在一个interest为readable的selector上,这个selector的兴趣就是喜欢观察挂在它身上的socketchannel有没有变成readable可读取数据状态的,一旦有就能立马把他们找出来交给别人去处理。当然还有writable之类的状态这里不细说。我们比较BIO与NIO对于接受连接读取数据这一过程就会发现,NIO不需要对每一个acceptable的连接和每一个readable的连接都安排一个线程去阻塞观察它们是否可连接可读取,只安排了两个selector线程去观察它们的状态变化。这两个selector去轮询socketchannel状态的策略像极了用一个定时任务去轮询数据库批量处理数据,定时任务因为有执行周期的间隔肯定不能立马处理每一条刚加入数据库的数据,最坏的情况下一条数据在加入数据库到被处理可能要进过一个定时任务的执行周期,但是如果数据本身对立马执行的需求不大或者将执行周期缩短到一个可接受的范围,比起对每一条数据都立马进行处理,这个无足轻重的延迟带来的是性能上的飞跃!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值