??xml version="1.0" encoding="utf-8" standalone="yes"?>
1、thread-per-request 的方式,q样会有更多U程l护和切换的pȝ开销Q同时在pȝ扩展性方面受到限制?/span>
2、针寚w?Q我们可以采用线E池的方式来节省U程创徏、维护以及切换的开销Q但是这样也会限制系l可以同时处理客L的数量,臛_对一些长q接协议来说是这栗此时增加线E池的大是不能再提高系l性能的,而只会增加系l更多的U程开销?/span>
3、传l的socket在读/写数据以及徏立连接上都是d式的(没有数据可读可能会阻塞;没有_I间~存传输的数据可能阻塞;服务端的acceptҎ以及socket构造函数都会阻塞等待,直到q接建立) 。这些特性会降低整个pȝ对CPU的利用率以及pȝ的活跃性,降低pȝ对客戯求的响应性及响应旉Q在某些情况下是不可接受的甚至会带来N性的l果。在q样的情形下Q我们要解决cpu利用率、线E活跃性以及提高系l吞吐量Q我们势必做很多额外的工作且相当复杂?/span>
4、由于传lsocket的阻塞特性,每个对等端都在阻塞等待另外一端完成相兛_理,q样势必增大死锁的风险?/span>
5、当然ؓ了提高系l的z跃性,传统的socket在accept、构造socket以及readҎ上都增加了超时控制的处理以及使用socket.closeҎ来打断一些阻塞操作,而网lL不确定的Q设|这些超时时间的讄在具体的上下文环境中的取g是比较复杂的。简而言之,Z提高pȝ的活跃性会增大pȝ的复杂度?/span>
那么QJava nio真的是Java socket~程解决以上若干问题的灵丹妙药吗?{案是否定的?/span>
nio的非dҎ是nio最大的特点Q所谓非d无非是通信的信道设|成为非d的情况下Q对该信道的所有操作都是会立即q回的。如数据dQ没有数据的时候会q回0而不是阻塞在信道上。这样就增大了系l的z跃性,使得pȝ不必费资源的I/O操作上,pȝ可以更好的利用cpu资源做一些其它处理,在某些场景下会提高系l的响应性以及吞吐量?/span>
同时nio在网l通信的中采用的网lI/O事g驱动的方式,x作系l对用户感兴的通信信道及其上面的I/O事gq行监听q知应用E序。这实际上也是观察者模式的一U应用,在这L背景下,问题4中的死锁风险几乎没有了?/span>
如果你开发的服务端不是P代服务器(序化处理每个客戯?Q那么对于问??在nio服务器中也是一L。换句话_我们开发的q发处理服务器ؓ了实现对各种|络I/O事g的处理,q对每种我们所兛_的网lI/O事gq行及时响应Q采用thread-per-request或者线E池的方式是无法避免的。所以很多h会感觉nio的网l编E结构与非nio的网l编E结构实际是一LQaccept换成了selectQ监听连接入站编E了监听信道上感兴趣的I/O事gQؓ了提高系l的处理能力Q还是要启动异步的线E来处理信道上的|络I/O事gQ只是具体实C一栯已。这说明nioq没有改变我们服务端E序~写的整体结构,只是在nio的环境下Q我们的可以去提高pȝ的活跃性、响应性和吞吐量。nio与非nio在读/写网l数据以及连接徏立等|络操作上是没有多大区别的,q些因素主要都还是取决于|络状况、操作系l协议栈实现、应用自w处理网l数据的方式{多个方面。甚臻I我们在n用nio的同时在一定程度上q会增大了网l编E的复杂度,因ؓ数据的读写以及连接的建立{操作变得更加不定Q当然最l网l编E的复杂q是取决于协议的复杂度?/p>