Java网络编程精解讲义4.ppt_第1页
Java网络编程精解讲义4.ppt_第2页
Java网络编程精解讲义4.ppt_第3页
Java网络编程精解讲义4.ppt_第4页
Java网络编程精解讲义4.ppt_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Java网络编程,作者:孙参考书籍:技术支持网站:第4章非阻塞通信,参见Java网络编程第4章,4.1线程阻塞概念4.2主类4.2 java.nio包4.3服务器编程示例4.3.1创建阻塞回声服务器4.3.2创建非阻塞回声服务器4.3.3在回声服务器4.4中混合阻塞模式和非阻塞模式客户端编程示例4.4.1创建阻塞回声客户端4.4.2创建非阻塞回声客户端4 . 4 . 2在生活中,最常见的堵塞现象是高速公路上的交通堵塞。汽车在高速公路上跑得很快。如果前面的交通堵塞,他们必须停下来,等到高速公路变得平坦后才能继续行驶。由于某些原因,线程在运行中也会被阻塞。处于阻塞状态的所有线程的共同特征是:放弃中

2、央处理器,暂停操作,只有在阻塞原因消除时才恢复操作;或者被另一个线程中断,该线程将退出阻塞状态并抛出中断异常。4.1.1线程阻塞的原因,线程阻塞的主要原因如下:线程执行线程休眠方法,线程放弃CPU,休眠n毫秒,然后恢复运行。当一个线程需要执行一个同步代码时,它不能获得相关的同步锁,所以它必须进入阻塞状态,并且在获得同步锁之前不能继续运行。线程执行对象的wait()方法,并进入阻塞状态。只有当其他线程执行对象的notify()或notifyAll()方法时,它们才能被唤醒。当线程执行输入/输出操作或远程通信时,它将进入阻塞状态,因为它等待相关的资源。4.1.1线程阻塞的原因在远程通信过程中,在客

3、户端程序中,线程可能在以下情况下进入阻塞状态:当请求与服务器建立连接时,它将进入阻塞状态,直到连接成功。当一个线程从Socket的输入流中读取数据时,如果没有足够的数据,它将进入阻塞状态,并且它不会从输入流的read()方法返回或者被异常中断,直到读取了足够的数据,或者它到达输入流的末尾或者发生异常。当一个线程向Socket的输出流中写入一批数据时,它可能会进入阻塞状态,并且不会从输出流的write()方法返回或者异常中断,直到所有数据都被输出或者出现异常。当调用Socket的setSoLinger()方法设置关闭Socket的延迟时间时,当线程执行Socket的close()方法时,它将进入

4、阻塞状态,并且不会从close()方法返回,直到底部Socket发送所有剩余数据或者超过setSoLinger()方法设置的延迟时间。4.1.1线程阻塞的原因,在服务器程序中,线程可能在以下情况下进入阻塞状态:线程执行服务器套接字的accept()方法,等待客户的连接,只有在接收到客户连接后才从accept()方法返回。当一个线程从套接字的输入流中读取数据时,如果输入流没有足够的数据,它将进入阻塞状态。当一个线程向Socket的输出流中写入一批数据时,它可能会进入阻塞状态,并且不会从输出流的write()方法返回或者异常中断,直到所有数据都被输出或者出现异常。4.1.1线程阻塞的原因,可以看出

5、,无论是在服务器程序还是在客户端程序中,当通过Socket的输入流和输出流读写数据时,都可能进入阻塞状态。这种可能被阻塞的输入输出操作称为阻塞输入输出。相反,如果在执行输入输出操作时没有阻塞,则称为非阻塞输入输出。4.1.2服务器程序使用多线程来处理阻塞通信的限制。(Java虚拟机为每个线程分配独立的堆栈空间。工作线程的数量越多,系统开销就越大。此外,它增加了在Java虚拟机中调度线程的负担,增加了线程间同步的复杂性,并提高了线程死锁的可能性。(2)大量工作线程的时间浪费在阻塞输入输出操作上。Java虚拟机需要频繁地转移CPU的使用权,使进入阻塞状态的线程放弃CPU,然后将CPU分配给运行状态

6、的线程。4.1.2服务器程序使用多线程处理阻塞通信的限制,工作线程越多越好。如图4-2所示,保持适当数量的工作线程将提高服务器的并发性能,但是当工作线程的数量达到一定的限制并超过系统负载时,将降低并发性能,这使得大多数客户无法快速从服务器获得响应。4.1.3无阻塞通信的基本思想是,服务器程序只需要一个线程来负责接收客户的连接,接收每个客户发送的数据,并将响应数据发送给每个客户。服务器程序的处理流程如下:当(等待接收连接就绪事件、读取就绪事件或写入就绪事件发生时)/如果有客户端连接,则阻塞接收客户端的连接;/如果(套接字的输入流中有可读数据)从输入流中读取数据,则为非阻塞;/如果(套接字的输出流

7、可以写入数据)将数据写入输出流,则为非阻塞;/无阻塞上述处理流程采用轮询方式。当某个操作准备好时,它将被执行;否则,检查是否还有其他准备好的操作要执行。线程不会仅仅因为一个操作没有准备好就被卡住,而只是等待操作准备好。4.2主要类4.2 java.nio包,提供支持非阻塞通信的类,主要包括:服务器套接字通道:服务器套接字的替代类,支持阻塞通信和非阻塞通信。socket channel:socket的一个替代类,支持阻塞通信和非阻塞通信。选择器:监控和接收服务器套接字通道的连接就绪事件,并监控套接字通道的连接就绪、读就绪和写就绪事件。选择键:代表服务器套接字层和套接字层向选择器注册事件的句柄。当

8、选定键对象位于选择器对象的选定键集合中时,表示与该选定键对象相关的事件已经发生。4.2 java.nio包中的主要类,4.2.1 Buffer,数据输入和输出经常是耗时的操作。缓冲区从两个方面提高了输入输出操作的效率:减少实际的物理读写次数。创建缓冲区时,会分配内存,并且该内存区域一直被重用,这可以减少动态分配和回收内存区域的次数。Java.nio包公开了缓冲区应用编程接口,使Java程序可以直接控制和使用缓冲区。4.2.1缓冲区。图4-4显示了缓冲类的层次结构。4.2.1缓冲区缓冲区,所有缓冲区都具有以下属性:容量:它指示缓冲区中可以存储多少数据。限制:表示缓冲区的当前结束点,不能读写超过缓

9、冲区限制的区域。限值可以修改,有利于缓冲液的重复使用。例如,假设一个容量为100的缓冲区已被数据填满,然后当程序重用该缓冲区时,它只向缓冲区中从位置0到位置10的区域写入10个新数据。此时,可以将限制设置为10,这样就无法读取之前的数据。该限制是非负整数,不应大于容量。位置:指示缓冲区中下一个读/写单元的位置,每次读/写缓冲区中的数据以准备下一次读/写时,该位置都会改变。该位置是非负整数,不应大于限制值。上述三个属性之间的关系是:容量=极限=位置=0,4.2.1缓冲区,缓冲区提供了一种改变上述三个属性的方法:清除():将极限设置为容量,然后将位置设置为0。翻转():将限制设置为位置,然后将位置

10、设置为0。倒带():将位置设置为0,不改变限制。4.2.1缓冲区,缓冲区类的剩余()方法返回缓冲区的剩余容量,其值等于极限位置。缓冲区类的compact()方法删除缓冲区中从0到当前位置的内容,然后将当前位置的内容复制到从0到限制位置的区域的限制中。如图4-6所示,当前位置和限制的值相应地改变。缓冲区类是一个抽象类,不能被实例化。有八个特定的缓冲区类,其中最基本的缓冲区是字节缓冲区,它存储的数据单元是字节。ByteBuffer类不提供开放式构造方法,但提供了两种获取ByteBuffer实例的静态工厂方法:allocate(int capacity):返回一个ByteBuffer对象,参数cap

11、acity指定缓冲区的容量。直接分配(int capacity) :返回一个ByteBuffer对象,参数capacity指定缓冲区的容量。该方法返回的缓冲区称为直接缓冲区,可以更好地与当前操作系统耦合,从而进一步提高输入输出操作的速度。然而,分配直接缓冲区的系统开销非常高,因此它仅在缓冲区很大并且存在很长时间,或者需要频繁重用时才使用。4.2.1缓冲区缓冲区,所有特定的缓冲区类都提供了读取和写入缓冲区的方法:get():相对读取。从缓冲区的当前位置读取一个单位的数据,读取后在该位置加1。Get(int index):绝对读取。从参数索引指定的位置读取一个单元格的数据。Put():相对写作。向

12、缓冲区的当前位置写入一个数据单元,并在写入后向该位置添加1。Put(int index):绝对写入。将一个数据单位写入参数索引指定的位置。4.2.2字符集,字符集类提供编码和解码方法:字节缓冲区编码(String str):对参数字符串指定的字符串进行编码,将获得的字节序列存储在字节缓冲区对象中,然后返回。字节缓冲区编码(CharBuffer cb):对参数cb指定的字符缓冲区中的字符进行编码,将获得的字节序列存储在字节缓冲区对象中,然后返回。CharBuffer decode(ByteBuffer bb):对ByteBuffer中由参数bb指定的字节序列进行解码,将获得的字符序列存储在Cha

13、rBuffer对象中,然后返回。4.2.2字符编码字符集,字符集的静态forName(字符串编码)方法,字符集返回一个字符集对象,它表示由参数encode指定的编码类型。例如,下面的代码创建了一个表示“GBK”编码的Charset对象:4.2.3通道,用于连接缓冲区和数据源或数据接收器(即数据目的地)。如图4-8所示,来自数据源的数据通过通道到达缓冲区,来自缓冲区的数据通过通道到达数据宿。通道接口只声明了两种方法:close():关闭通道。IsOpen():确定通道是否打开。通道在创建时打开,一旦关闭,就不能重新打开。4.2.3通道通道,ReadableByteChannel接口:声明read

14、(ByteBuffer dst)方法,该方法将数据源的数据读取到参数指定的ByteBuffer中。WritableByteChannel接口:声明write(ByteBuffer src)方法,该方法将参数指定的ByteBuffer中的数据写入数据接收器。分散字节通道接口:ReadableByteChannel接口被扩展,允许分布式读取数据。GatheringByteChannel接口:可写字节通道接口被扩展以允许数据的集中写入。文件通道类:它是通道接口的实现类,代表一个与文件相连的通道。该类实现字节通道、分散字节通道和聚集字节通道接口,支持读操作、写操作、分布式读操作和集中写操作。可选通道类

15、:它也是一个通道,不仅支持阻塞的输入输出操作,还支持非阻塞的输入输出操作。4.2.3 Channel,SelectableChannel有两个子类:ServerSocketChannel类SocketchChannel类:SocketchChannel还使用读取(ByteBuffer dst)和写入(ByteBuffer src)方法实现字节通道接口。4.2.4 SelectableChannel类,它是一个支持阻塞输入/输出和非阻塞输入/输出的通道。在非阻塞模式下,读写数据不会被阻塞,SelectableChannel可以向选择器注册读就绪和写就绪事件。选择器负责监控这些事件。当事件发生时,如读取就绪事件,选择通道可以执行读取操作。,4.2.4选择频道类,选择频道的主要方法如下公共选择通道配置阻塞(布尔阻塞(引发异常公共选择密钥寄存器(选择

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论