基于java的判断dtu超时功能的研究与设计毕业论文设计(编辑修改稿)内容摘要:

ket 仍进行监听,通信链路建立后就可任意交换数据了。 当 DTU 长时间没有 发送数据到数据中心时,那么数据中心就认为 该 DTU 已掉线并 断开与该 DTU 的连接。 判断 DTU 超时 功能 是 DTU 众多功能之一,作用就是帮助数据中心及时发现那些不传送数据却仍然连接占用大量资源的 DTU,以便让有限的内存资源得到最大化利用。 5 图 1 DTU及其使用示例 与主要研究内容 课题的总体目标 本课题的目标是,实现个 判断 DTU超时 的功能 , 使用这个功能可以使服务器很大程度上提高自己管理内存资源的能力。 此功能 应用于服务器后台上,能比较理想得保证通讯连接的时效性,避免了那些 空占其位,不尽 其守的 DTU。 研究的主要内容 下面就本课题所做的工作的主要内容 1) 就具体的 DTU设备进行调研,找出其工作原理,以何种方式发送数据等等。 2) 编写服务器端接受数据的程序,能够从字节流里读取数据。 3) 编写服务器端轮询程序,能够每隔一段时间检查一次各客户端是否掉线。 本论文的章节安排 第 2 章,提出了课题的总体目标与主要研究内容; 第 3 章,对判断 DTU超时功能的总体设计,对设计有个宏观把握; 第 4 章,对判断 DTU超时功能的具体设计,详细介绍了设计过程。 第 5 章, 针对本文的工作进行了总结以及提出不足之处。 6 3 总体设计 需求分析与设计思想: 对判断 DTU超时功能的需求分析 在互联网日益发展的今天, DTU 的使用也越来越广泛 , 为各行业之间的信息、产业融合提供了帮助。 可往往运用 DTU 的过程中难免会遇到令人不快的情况使得 DTU 无法正常向 服务器 发送数据 , 这些情况常见有:突然断电、 DTU 本身电路故障、信号太弱、等等。 服务器与众多 DTU 通讯时,可能某一 DTU 故障而无法向服务器发送数据,此时服务器还在 默默等待该 DTU 传送的信息。 大家都知道服务器根本接受不到该 DTU 发来的数据,但是此时服务器还与该DTU 连接着,占着服务器宝贵的内存资源双方却不能正常通讯,显然这浪费资源,要是众多 DTU 都是这样 尸位素餐的话 ,总有某一刻服务器也被“卡死了”。 所以为了消除这种隐患,迫切需要一种功能能够准确查出那些 尸位素餐 的 DTU,然后把它们“踢下线” 以释放资源。 对判断 DTU超时功能的设计思想 启动服务器,打开了轮询程序并启动了监听程序,等候客户端的连接。 若有客户端发来连接请求时,服务器就专门为这个客户 端启动一个线程来接受并处理该客户端发来的数据;另外服务器会创建个节点来代表该客户端,并将该节点存在哈希表中。 节点里封装有客户端的 IP 地址、连接端口号、向服务器发送的数据、该节点在哈希表中存放的位置(即:键值)以及最后一次与服务器通讯时的时间(客户端向服务器发送一次数据,该时间即更新一次)。 轮询程序启动以后,会每隔一段时间轮询一次哈希表,对里面存储的客户端节点中的时间进行检查,若其大于指定值则默认该客户端节点已故障,将与其断开连接。 设计时用到的重要的技术或数据结构 同步锁 当我们用多线程访 问或修改同一共享资源时,可能会引起线程间的冲突,因此引入线程同步机制,来让先到的线程 率 先访问或修改该共享资源而 在 这一线程对共享资源的访问或修改还没有结束之前,任何要访问或修改该共享资源的线程都必须等待,这样就很好得解决了线程间的并发问题。 本设计中轮询机制的代码在访问或删除哈希表中的客户端节点时,必须考虑到此时可能有新的客户端向服务器端发出连接请求但是轮询尚未结束不能将新来的节点插入哈希表,所以要将轮询代码与向哈希表插入节点的代码同步起来。 同步分为 同步方法 和 同步块 两种方式。 Synchronized 加在方法上, (同步方法,锁定类实例 ) Java 代码 7 public class Demo1 { public synchronized void m1(){ //............... } public void m2(){ //............ synchronized(this){ //......... } //........ } } 这两种写法的效果是一样的,锁定的都是类实例。 如果有 两 个 类实例: de1 = new Demo1(), de2 = new Demo1(), 另外有两个线程: thread1, thread2,都调用了de1 对象,那么,在同一时间,如果 thread1 调用了 (),则 thread2 在该时间内不能访问 () 和 ()。 因为 thread1 把 de1 这 个对象的锁使用了,所以无法分给其它线程使用。 但是,如果 thread1 调用 (), thread2 调用 (), 则可以同时进行,因为它们调用的是不同的 Demo1 类对象实例。 Synchronized 加在变量上, (同步块,锁定类实例 ) Java 代码 public class Demo2 { Object a = new Object()。 Object b = new Object()。 public void m1(){ //............ synchronized(a){ //......... } //........ } public void m2(){ //............ synchronized(b){ //......... } //........ 8 } } 这种情况下,是实现代码块锁定,锁定的对象是变量 a 或 b。 (注意 :a 、 b 都是非 static 的 )如果有一个 类实例: do = new Demo2(),另外有两个线程 :thread1,thread2,都调用了 do 对象,那么,在同一时间,如果 thread1 调用了 (),则thread2 在该时间内可以访问 ()。 但不能访问 () 的同步块, 因为 a 被 thread1 锁定了。 若此代码里 a、 b 变量用 static 修饰, 其锁定的对象都是类 Demo2,而不是类 的 实例,即在多线程中,其 共享的资源是属于类的,而不是属于类对象的。 在这种情况下,如果 thread1 访问了这 2 个方法中的任何一个, 在同一时间内其它 任何 线程都不能访问 这 2 个方法。 哈希表 哈希表的定义及其构造方法 哈希表是一种重要的存储方式,也是一种常见的检索方法 ,是 基于 哈希表 的 Map 接口的实现。 此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。 除了非同步和允许使用 null 之外, HashMap 类与 Hashtable 大致相同。 其基本思想是将关系码的值作为自变量,通过一定的函数关系计算出对应的函数值,把这个数值解释为结点的存储地址,将结点存入计算得到存储地址所对应的存储单元。 检索时采用检索关键码的方法 寻找对应的节点。 现在哈希表有一套完整的算法来进行插入、删除和解决冲突。 在 Java 中哈希表用于存储对象,实现快速检索。 K,V提供了 若干种 方法让用户 很方便地 使用哈希表,而不需要考虑其真正如何工作 的。 哈希表类中提供了三种构造方法,分别是: public HashMap () public HashMap (int initialcapacity) public HashMap (int initialCapacity,float loadFactor) public HashMap(Map? extends K,? extends V m) 参数 initialCapacity 是 HashMap 的初始容量,它的值应大于 0。 loadFactor 又称装载因子,是一个 到 之间的 float 型的浮点数。 它是一个百分比,表明了哈希表何时需要扩充,例如,有一哈希表,容量为 100,而装载因子为 ,那么当哈希表 9 90%的容量已被使用时,此哈希表会自动扩充成一个更大的哈希表。 如果用户不赋这些参数,系统会自动进行处理,而不需要用户操心。 HashMap 提供了基本的插入、检索等方法。 ■ 插入 public V put(K key,V value) 在此映射中关联指定值与指定键。 如果该映射以前包含了一个该键的映射关系,则旧值被替换。 ■ 检索 public boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true。 public SetK keySet() 返回此映射中所包含的键的 Set 视图。 该 set 受映射的支持,所以对映射的更改将反映在该 set 中,反之亦然。 如果在对 set 进行迭代的同时修改了映射(通过迭代器自己的 remove 操作除外),则迭代结果是不确定的。 该 set 支持元素的移除,通过 、 、 removeAll、 retainAll 和 clear 操作可从该映射中移除相应的映射关系。 它不支持 add 或 addAll 操作。 public CollectionV values() 返回此映射所包含的值的 Collection 视图。 该 collection 受映射的支持,所以对映射的更改将反映在该 collection 中,反之亦然。 如果在对 collection 进行迭代的同时修改了映射(通过迭代器自己的 remove 操作除外 ) ,则迭代结果是不确定的。 该collection 支 持 元 素 的 移 除 , 通 过 、 、removeAll、 retainAll 和 clear 操作可从该映射中移除相应的映射关系。 它不支持 add 或 addAll 操作。 public SetK,V entrySet() 返回此映射所包含的映射关系的 Set 视图。 该 set 受映射支持,所以对映射的更改将反映在此 set 中,反之亦然。 如果在对 set 进行迭代的同时 修改了映射(通过迭代器自己的 remove 操作,或者通过在该迭代器返回的映射项上执行 setValue 操作除外),则迭代结果是不确定的。 该 set 支持元素的移除,通过 、 removeAll、 retainAll 和 clear 操作可从该映射中移除相应的映射关系。 它不支持 add 或 addAll 操作。 10 ■ 删除 public V remove(Object key) 从此映射中移除指定键的映射关系(如果存在)。 public void clear() 从此映射中移除所有映射关系。 此调用返回后,映射将为空。 线程 线程的设计 在 Java 中,创建线程的方法有两种:一种是通过创建 Thread 类的子类来实现;另一种是通过实现 Runnable 接口的类来实现。 这两种创建线程方法并没有本质上的区别,但是由于 Java 不允许多重继承,所以当一个类 要继承另一个非 Thread 类而实现多线程的话,只能通过实现 Runnable 接口的方式来实现。 通过 Thread 类实现 定义一个线程类,他继承类 Thread 并重 写其中的 run()方法。 这时在初始化这个类的实例时,目标对象 target 可以为 null,表示这个实例本身具有线程体。 由于 Java 只支持单继承,用这种方法定义的类不能再继承其他类。 1 Thread 类定义的用来帮助管理线程的方法主要包括以下内容 : ● void run()方法:线程的入口点,运行线程中的代码。 ● void start()方法:通过调用运行方法来启动线程,使之由出生状态转入就绪状态。 ● void sleep(long milis):在一段时间内挂起线程,令线程睡眠, 在此期间,线程不消耗 CPU资源;以毫秒为单位。 ● void interrupt():中断线程。 ● boolean isAlive():判定线程是否仍在在运行,出于活动状态。 ● void stName(String threadName):改变线程的名字。 ● String getName():获取由 setName()方法实质的线程名字的字符串。 11 ● Yield():将 CPU 控制权主动移交到下一个可运行的线程。 ● setPriority(int p):设置线程优先级。 ● getPriority():获得线程优先级。 ● Join():等待一个线程终止。 实现 Runnable 接口 创建线程的最简单的方法就是创建一个实现 Runnable 接口的类。 然后根据工作需要重新设计线程的 run 方法;再建立该类的对象。 Runnable 抽象了一个执行代码单元。 你可以通过实现 Runnable 接口的方法创建每一个对象的线程。 为实现 Runnable 接口,一个类仅需实现一个 run()的简单方法。 线程的生命周期 每个线程的生命周期一共包括 5 种状态:出生,就绪,运行,阻塞和死亡。 线程 从出生到死亡的过程称为线程的生命周期。 通过特定的操作可以进行状态间的转换。 出生 当用关键字 new 和 thread 类或其子类建立了一个线程对象后,该线程就处于出生状态。 Thread 线程名 =new Thread(); 处于新建状态的线程只是一个空闲的线程对象,系统并没有为他分配资源。 在调用start 方法之前,线程就一直处于出。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。