博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
非阻塞通信——Java
阅读量:3936 次
发布时间:2019-05-23

本文共 2023 字,大约阅读时间需要 6 分钟。

一、实验目的和要求

1.掌握Java非阻塞通信机制,掌握java.nio中ServerSocketChannel、SocketChannel、Selector、SelectionKey等关键类的使用;

2.掌握使用java.nio包中的类创建非阻塞模式的服务器和客户程序的方法。

二、实验内容

1. 分析说明

(1)说明导致线程阻塞的主要原因;
答:导致线程阻塞的原因主要有以下几个方面:

  • 线程执行了Thread.sleep(int n)方法,线程放弃CPU,睡眠n毫秒,然后恢复运行
  • 线程要执行一段同步代码,由于无法获得相关的同步锁,只好进入阻塞状态,等到获得了同步锁,才能恢复运行
  • 线程执行了一个对象的wait()方法,进入阻塞状态,只有等到其他线程执行了该对象的notify()或notifyAll()方法,才可能将其唤醒
  • 线程执行I/O操作或进行远程通信时,会因为等待相关的资源而进入阻塞状态。例如,当线程执行System.in.read()方法时,如果用户没有向控制台输入数据,则该线程会一直等读到了用户的输入数据才从read()方法返回。

(2)分析说明java.nio中进行非阻塞通信时,使用的主要类的功能及其相互关系。

答:

  • ServerSocketChannel:ServerSocket的替代类,支持阻塞通信与非阻塞通信。
  • SocketChannel:Socket的替代类,支持阻塞通信与非阻塞通信。
  • Selector:为ServerSocketChannel监控接受连接就绪事件,为SocketChannel监控连接就绪,读就绪和写就绪事件。
  • SelectionKey:代表ServerSocketChannel及SocketChannel向Selector注册事件的句柄。当一个SelectionKey对象位于Selector对象的selected-keys集合中时,就表示与这个SekectionKey对象相关的事件发生了。
  • ByteBuffer表示字节缓冲区,SocketChannel的read()和write()方法都会操纵ByteBuffer。ByteBuffer类继承于Buffer类。ByteBuffer中存放的是字节,为了把它们转换为字符串,还需要用到Charset类,Charset类代表字符编码,它提供了把字节流转换为字符串(解码过程)和把字符串转换为字节流(编码过程)的实用方法
    在这里插入图片描述
    2. 课本例4-1EchoServer.java(线程池阻塞模式)及例4-2EchoServer.java(非阻塞模式)的分析与调试运行。
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

(1)分析例4-1,说明可能导致线程阻塞的语句。

答: 有以下几点有可能会导致阻塞的发生。
1)服务端等待客户端连接:
在这里插入图片描述
线程执行 accept()方法,等待客户的连接,直到收到了客户连接,才从accept()方法返回。
2)线程从Socket的输入流读入数据时,如果没有足够的数据,就会进入阻塞。
在这里插入图片描述
Socket的输入流br利用readLine()方法读取一行字符串,如果一直没有数据输入,就会阻塞。
3)线程向Socket的输出流写一批数据时,可能会进入阻塞。
在这里插入图片描述
线程向Socket的输出流写一批数据时,由于写数据需要一定的时间,等到输出所有的数据或发生异常,才从输出流的write()方法返回或异常中断。
(2)分析例4-2,图示EchoServer.service方法的主要框架,说明其中主要对象的关系。
在这里插入图片描述
在service()方法中,ServerSocketChannel向Selector注册接收连接就绪事件。监听事件发生,将SelectionKey对象加入到selected-keys集合中。利用accept()方法获得与客户连接的SocketChannel对象。SeverSocketChannel向register()方法传递了一个ByteBuffer类型参数,ByteBuffer将作为附件,与新建的SelectionKey对象关联。
(3)改进、调试、运行上述两个例子,给出运行结果及分析说明。
4-1运行结果:
在这里插入图片描述
在这里插入图片描述
4-2运行结果:
在这里插入图片描述
在这里插入图片描述
三、实验总结
1.实验过程中遇到的问题及解决办法;
答:在实验过程中,对于阻塞模式和非阻塞通信编程的思路不是很了解
解决:尽管阻塞模式与非阻塞模式都可以同时处理多个客户连接,但阻塞模式需要使用较多的线程,而非阻塞模式只需使用较少的线程,非阻塞模式能更有效地利用CPU,系统开销小,因此有更高的并发性能。阻塞模式比较适用于同步通信,并且通信双方稳定地发送小批量的数据,双方都不需要花很长时间等待对方的回应。非阻塞模式编程相对难一些,对ByteBuffer缓冲区的处理比较麻烦。非阻塞模式比较适用于异步通信,并且通信双方发送大批量的数据,尽管一方接收到另一方的数据可能要花一段时间,但在这段时间内,接收方不必傻傻地等待,可以处理其他事情。

转载地址:http://ovmgn.baihongyu.com/

你可能感兴趣的文章
CHECK opengl version
查看>>
scatter and gather in thrust
查看>>
block compressed sparse row (BSR) matrix format
查看>>
第一章 在VS2008下如何配置好CG环境
查看>>
disable the touchpad by shortcut on the ubuntu
查看>>
build openni with gcc 7
查看>>
install git-lfs on ubuntu and use it
查看>>
git submodule的工作原理
查看>>
709 SLIM
查看>>
specify gcc for MATLAB on ubuntu
查看>>
add matlab to launch bar on ubuntu
查看>>
how to solve undefined reference in igllib
查看>>
project a vertex along its normal onto a triangle
查看>>
install maya2017 on ubuntu 16.04
查看>>
VS2008下改变项目的默认属性
查看>>
第二章 如何在VS2008里面编译CG
查看>>
第四章 各种变换的原理---GL版本
查看>>
3D数学之矩阵的各种求逆
查看>>
3D数学之四元组应用及实现
查看>>
map floats between 0 and 1 to colorvector
查看>>