OO面向对象多线程编程作业总结
第五次作业:多线程电梯调度
设计策略
在本次电梯作业当中,我构造了一个电梯请求队列线程,一个调度器线程,三个电梯线程,一个文件输出线程,还有主线程。
调度器扫描用户的请求队列,将每个队列分配给符合要求的电梯,每个电梯有自己的请求队列,电梯根据自己的请求队列来改变自身状态。
同步控制主要包含两个点:用户请求队列会被调度器和请求队列输入线程操作,需要进行同步控制,电梯内部的运行队列也会被电梯本身和调度器操作,也需要进行同步控制。
同步控制上,我用了synchronized关键词和wait()与notify()的方法来实现对共享资源的线程安全操作。
度量分析及类图
- 类图:
- 度量分析:
在类的度量分析里面,调度器类和电梯类的复杂度较高,接着分析方法的复杂度。
在调度器中,判断是否能捎带的方法复杂度较高,实际上这一部分完全可以通过模拟电梯按钮来执行,在bug分析中提到。调度电梯的方法复杂度也较高,主要是要判断电梯外的请求,分析每部电梯的累计运动量等,这里可以更加模块化一些。
电梯类的复杂度主要是方法过多,每次停在某个楼层之后都要重新计算最短的捎带请求。改变思路可以让代码简洁很多。
还有我的请求队列中的run()方法当中,我把输入的各种判断全部写在run当中了,这是很不好的习惯,应该让线程的run方法尽量简洁,把输入的操作模块化。
bug分析
这次作业我在提交之前几个小时才发现一个很重要的bug,这是我在设计思路上的一个缺陷导致的,而且指导书也没有认真阅读。在请求加入请求队列的时候,如果是电梯内的请求应该直接分配给对应的电梯,不需要等待电梯都处于能捎带或者等待服务的状态,而我却让电梯内请求等待了。最后修改的时候直接将请求强行加入到电梯队列当中,这样又导致了捎带问题。
实际上较好的设计思路应该是模拟真实的电梯,给电梯的每一层设置按钮,当有请求发送的时候,改变按钮的状态,在每一层运行的时候都判断按钮是否被按下,如果是同质请求就忽略。
还有就是线程时间的控制上面有较大的误差,不是特别精确。
发现别人的bug
这次我测试的同学的bug主要出在格式问题上面,输出的时候括号很多没有按照指导书的要求输出。
第六次作业:IFTTT文件管理系统
设计策略
本次作业中,我从主线程开启输入控制器,从输入中获取需要开启的文件监控器,监控器线程开始对文件进行实时监控,测试线程也同时开启,对文件进行修改操作,监控器检测到文件的变化,将信息发送给操作线程,对相应的文件执行相应的操作。
在同步控制方面,对文件信息的读取和修改需要进行同步操作。
还有一个stop线程是用来控制系统终止的,输入相应的指令,系统会自动退出。
度量分析及类图
- 类图:
- 度量分析:
在InputHandler当中,平均操作复杂度较高,因为在判断格式的方面写的代码较长,可以考虑更加模块化的判断。
各个触发器的平均操作复杂度也比较高。这也和我的设计思路有关,因为一开始没有注意到很多触发器需要监控目录下所有文件的变化,所以一开始没有对文件夹进行监控,后来增加了文件夹监控以后,代码变得冗长。
其实可以用嵌套循环单个文件监控的方式实现文件夹的监控,这样写起来会比较简洁。
bug分析&自我分析
bug
在测试较深的目录的时候,我的输出情况会很不稳定,比如未删除前一次的recorddetail.txt的话很容易会不稳定,线程安全的问题没有解决。
自我分析
我把所有的类放在了默认的package里面,这样的架构不是很好。监控器类和操作类都可以分别放在单独的包中,监控器类也可以写成继承一个父类的方式,他们都有对文件进行监控的功能。我的程序的可拓展性和可维护性还有所欠缺。
程序比较好的地方是用了一个Operation类来对操作进行选择,每次只需要调用Operation,而不需要单独调用每个操作的方法。
发现别人的bug
对方在线程安全的设计上有所欠缺,很多文件进行了修改以后监控器可以检测到,但是并没有进行相应的操作,导致了很多输出是空。
第七次作业:出租车调度系统
设计策略
对于每一个出租车,我都开了一个线程,每一个符合要求的请求,我都会开一个调度器线程来对出租车进行调度,把符合要求的出租车加入到调度器线程的队列当中,调度器线程运行了3s以后,从队列中筛选出最合适的出租车并将请求发送给出租车执行,请求执行过程中,出租车需要被上锁,防止其他调度器线程对出租车进行调度。
度量分析及类图:
类图:
这次把不同功能模块放在了不同的package里面,information用来存储数据,taxi用来存储出租车和出租车队列,locaiton用来存储坐标和地图,scheduler用来调度,passenger用来存储请求队列,输入请求。
度量分析:
除去gui,平均复杂度最高的是taxi类,taxi的移动和状态转换的确需要很多函数来判断实现,所以不可避免的复杂度升高。
bug分析&自我分析
起点终点一致的时候我没有判断错误,而是让出租车进行接单。还有出租车信息文件的输出没有实时输出。
老问题,输出的时间间隔又有误差。发现系统的sleep方法的确会产生误差,所以后面自己写了个sleep的方法进行精确的控制睡眠时间。
本来这次作业想使用观察者模式,但是由于涉及的观察者类不是很多,我用了observer和notifier以后反而使代码变得十分冗杂,所以最后还是放弃了使用这种方法,感觉设计模式上还需要多加研究。
发现别人的bug
在线程调度的时间发现了问题,同时输入两条同样的请求被当做两个时间的请求,可能是中间代码出现了延迟。
在出租车自由行走以后,通过控制台输出,发现有些没有在规定时间停止一秒。
还有寻找最短路径的过程没有输出。
心得体会
1、在代码结构和设计模式上还需要多加研究,从一开始把所有类都写在一起,到后面对不同类的功能分门别类,也有了一些进步。对于接口和抽象类的使用还需要多加练习,增强程序的可维护性和可拓展性。
2、在线程的控制方面,总是会在时间的精确度上出一些问题,主要是在线程的调度方面会发生一些延迟,这些问题目前还没有找到合适的解决方案,现在能做的就是尽量简化代码的运行量。
3、感觉每次做作业之前都没有进行系统的学习就开始写代码,导致中间很多环节不会写又要到回头去学习,而且没有一个整体的框架。还是要把基础知识巩固才行。
OO面向对象多线程编程作业总结的更多相关文章
- Java多线程编程作业总结
一.多线程知识总结 1.线程同步 有关创建线程的知识就不过多的叙述了.就从主要的开始讲吧,讲一下线程的同步.与操作系统中的进程同步一样,线程同样面临着资源共享的问题,怎样处理线程的资源共享是运用多线程 ...
- 【持续更新】JAVA面向对象多线程编程的一些tips
sleep()和wait()的区别 sleep()方法是Thread类的方法,wait()方法是Object类的方法. 调用sleep()方法的过程中,线程不会释放对象锁,睡眠时间一过,就又开始执行. ...
- Win32多线程编程(1) — 基础概念篇
内核对象的基本概念 Windows系统是非开源的,它提供给我们的接口是用户模式的,即User-Mode API.当我们调用某个API时,需要从用户模式切换到内核模式的I/O System Serv ...
- 面向对象OO第15次作业总结
面向对象OO第15次作业总结 1.论述测试与正确性论证的效果差异,比较其优缺点测试通过大量测试数据来覆盖测试代码,比较直观,优点在于知道测的是啥,特别直观,缺点在于很难覆盖所有情况.正确性论证从逻辑关 ...
- 面向对象OO第5-7次作业总结
面向对象OO第5-7次作业总结 学习OO七周了,深切的感受到了这门课程的不友好.前三次作业能够算是勉强地通过了,但是从第五次作业开始就完全GG了.这三次作业,从多线程电梯开始,然后文件监控,然后到出租 ...
- 面向对象OO第1-3次作业总结
面向对象OO第1-3次作业总结 学习OO已经四周了,对OO以及JAVA的编程也算终于了解了一丢丢.现在做完了三次的编程作业,对前三次的作业做一次总结. 第一次作业 ------------------ ...
- OO面向对象课程作业1-3总结
作业一.多项式的加减运算 1.设计要点与自我分析 我设计的类图 老师建议类图 我设计了两个类来进行多项式的计算,类Polynomial进行多项式的存储和输入输出,第二个类进行多项式加减运算.而加减运算 ...
- 面向对象OO第9-11次作业总结
面向对象OO第9-11次作业总结 1.关于规格化设计的调研程序规格说明:对程序所应满足的要求,以可验证的方式作出完全.精确陈述的文件.“规格说明”一词与其他工业产品的“规格说明书”有相似的含义.不过, ...
- Python全栈day24(面向对象编程作业作业_定义学校老师课程班级学生类)
面向对象作业 作业_定义学校老师课程班级学生类.py #面向对象编程作业,定义学校老师课程班级学生类 #定义几个类,尽可能定义多的数据属性及函数属性 class School: def __init_ ...
随机推荐
- python group()--转载
import re a = "123abc456" print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0) ...
- Z-score(Z值)的意义--转载
http://blog.sina.com.cn/s/blog_72208a6a0101cdt1.html http://www.docin.com/p-350677620.html http://we ...
- json字符串在javascript和java代码中的表示方式
最近在使用js写json形式的字符串的时候,当我把json形式的字符串放到函数JSON.parse()的时候,总是报错Uncaught SyntaxError: Unexpected token ' ...
- python tcp
server import socket host="localhost" port= s=socket.socket(socket.AF_INET,socket.SOCK_STR ...
- 安装 mysql8.0.13 (Ubuntu 16.04 desktop amd64)
1.下载mysql deb https://dev.mysql.com/downloads/mysql/ #移动到/usr/local/src/目录,解压 sudo mv mysql-server_8 ...
- Jmeter 测试API接口 查看接口的幂等问题
背景介绍: 比如一个注册接口,要求填入的手机号与DB中已有的不能重复, 如果手机号码重复,则此次注册失败,不会新增会员数据: 如果不重复,则注册成功(忽略其他因素). 但是用20个并发,同样的请求,请 ...
- jstl中<c:forEach>的用法
在JSP的开发中,迭代是经常要使用到的操作.例如,逐行的显示查询的结果等.在早期的JSP中,通常使用Scriptlets来实现Iterator或者Enumeration对象的迭代输出.现在,通过JST ...
- [ios]ios读写文件本地数据
参考:http://blog.csdn.net/tianyitianyi1/article/details/7713103 ios - Write写入方式:永久保存在磁盘中.具体方法为:第一步:获得文 ...
- Codeforces 559B - Equivalent Strings
559B - Equivalent Strings 思路:字符串处理,分治 不要用substr(),会超时 AC代码: #include<bits/stdc++.h> #include&l ...
- robot 批处理文件
robot自带的ride工具不好用,就像填表格似的写脚本,太拘束.所以一直在用sublime text写robot脚本,但是也有问题:用sublime text写的脚本,只能运行一个文件的case,并 ...