在三次做业中,我都采用了经过一个共享队列,采用轮询(非暴力轮询)的方法进行信息的传递,在初次接触多线程时,因为惧怕产生死锁,故最初采用了这样的方法,但这样的信息交互方法,相对于普通生产者消费者模型的wait()
和notify()
方法确定效率较低,有许多无用的查询,在之后的练习中,仍是须要改为wait()
和notify()
。python
在考虑同步控制的方法时,我是采用syncronized
修饰临界区的方法来进行防止多个线程同时对一个临界资源进行操做。在刚接触多线程时,我记得最清楚的点就是ArrayList
是线程不安全的,Vector
是线程安全的。因为对于这一区别的不了解,我就在电梯第二次做业中,将全部的ArrayList
都替换成了Vector
,想以此来保证多线程的安全性。在后来本身的测试和资料的查阅中,我发现Vector
的线程安全体如今其方法的原子性,但在符合操做中仍是得使用锁的方法进行互斥访问,因此在这里ArrayList
和Vector
并无差异。算法
在第一次做业,因为没有性能分,就直接照搬傻瓜调度的方法进行程序的构建。安全
在第二次做业,采用(伪)Look算法进行调度,可是因为本身的设计失误使得本身作了一个零优化。(在电梯进行调度接人时,例如电梯上行接一个要下行的人,我会将请求指令派发给电梯,却没有电梯的调度中增长目的楼层的刷新和检测楼层是否有人须要进出,也就致使了增长的优化毫无心义)多线程
第三次做业,我沿用第二次的架构,调度器先静态拆分不可直达的指令,再经过请求的优先级(例如-3-3优先级最高)来派发指令架构
while (true) {
/*to split the personRequest*/
checkSplit();
for (int i = 1;i <= 3;i++) {
upDispatch(i);
}
for (int i = 1;i <= 3;i++) {
downDispatch(i);
}
if (waitList.isEmpty() && upList.isEmpty() &&
downList.isEmpty() && inputFlag.getFlag()) {
managerFlag.setFlag();
break;
}
Main.sleep(breakTime);
}
同时根据电梯的运行情况选择运送时间最短的电梯进行运送。性能
private ConcreteElevator chooseBestE(PersonRequest personRequest) {
long leastTime = 50000;//the max time
ConcreteElevator bestE = elevators[0];
for (ConcreteElevator concreteElevator : elevators) {
if (concreteElevator.isCarry(personRequest, isBypass)) {
long time = concreteElevator.costTime(personRequest, isBypass);
if (leastTime >= time) {
bestE = concreteElevator;
leastTime = time;
}
}
}
return bestE;
}
因为第二次做业问题没有发现,致使了我在第三次做业的负优化。(因为一个指令派发给某一个电梯,可是因为他没有捎带走,只能等他运行完其余指令才能运送这一指令,形成了很大的性能损失)测试
三次做业的类图以下所示:优化
本次做业较为简单,未发现什么问题atom
和第三次做业大致一致,在第三次做业中详述spa
在第三次做业中,主要的问题仍是电梯过于复杂,因为我分配请求是根据当前状况下哪个电梯运送这个请求最快来指派电梯,因此须要计算cost,为了减轻代码量就把这一部分放在了电梯中泽娜加了电梯的复杂度,这一部份内容本应该所有有调度器负责。解耦合状况我认为也还能够。
优势:在计算时间时,将部分实现代码放在了电梯中,减小了总体的代码量
缺点:在计算时间时,将部分实现代码放在了电梯中,增长了电梯和调度器之间的耦合,不利于类与类职责的拆分
第一次和第二次做业在公测和互测中没有bug。
在第三次做业中因为一些事情,太迟进行代码的编写,致使对于代码的测试不足,一个小小的疏漏公测出了一个bug。
for (int i = 1;i <= 3;i++) {
upDispatch(i);
}
for (int i = 1;i < 3;i++) {
downDispatch(i);
}
//漏了一个=,致使调度器一直有一个15-1的人没法派分出去,致使了程序的不能结束。
因为对于多线程有了大概清晰的了解,而且采用轮询的方法,没有出现多线程相关的蜜汁bug
我采用python生成随机数据,再使用管道实现不断喂数据给程序,再对结果进行正确性检测。在测试别人的程序时,使用随机数据进行测试,测出了4,5个bug,效果仍是不错的,在第二次做业时,因为知道有同窗被发现了bug,因此针对其代码结构编写了测试样例,找到了一个bug。其余所有采用随机测试的方法,将错误同窗的输入复制到其文件夹中,以随机字符串给其命名以防止覆盖。
这个单元的测试和上个单元的测试是彻底不一样的,由于这一次若是不使用评测机就根本没办法进行测试,评测机的编写也是一个小难点。并且第一次能够只依靠手动罗列各类状况手写测试样例来找bug,而此次即便构造出测试样例也没办法测试。
1:不能使用基本数据类型做为共享对象,最初使用Boolean来做为共享对象,后来发现这不是引用传递,而是值传递,致使程序不能正常结束。
2:Vector的安全性只体如今其方法的原子性上,在复合操做中不保证原子性。