第五次做业java
UML & Mertrics算法
电梯的调度问题,实质上就是任务的请求与分配问题,笔者在第五次做业中采用简单的“生产者-消费者”模型,创建了Din
线程做为生产者解析输入并增长运载请求,创建Elev
线程进行输出,待处理数据由主控类Ctrl
维护,并做为电梯“调度器”,前二者的操做由线程安全的Ctrl
负责,后两次做业也延续这样的架构,事实是无需重构也应付得了本次迭代。但笔者请求队列与调度器一体化,且只有一级调度,致使主控类异常臃肿。安全
第六次做业数据结构
UML & Mertrics多线程
还是老三样,第六次做业中扩展功能比较容易实现,进行相关类的方法扩写,主要是实现多电梯线程,笔者Ctrl
类的处理不是很好,下一次重写了Ctrl
架构
第七次做业测试
UML & Mertrics线程
架构上没有大的改动,为实现换乘功能,笔者创建了MyReq
类存储PersonRequst
与乘客现处楼号,并面向过程根据换乘地图为各型电梯创建了楼层映射机制设计
notify()
条件,竟然唤起了RUNNALBE
的线程,因为Ctrl
是共享的,致使输入被电梯线程阻塞,好在最终肯定了进入wait()
的条件。ElevatorInput.getElevatorNum()
,而是用(new Scanner(System.in)).nextInt()
,System.in
被输入接口与Scanner
共享,致使输入缓冲区线程不安全,笔者此次属实拉了胯了,直接白给愉悦送走C
型电梯上的乘客想去楼4
时,笔者直接给他送到楼3
,但楼3
只有C
能去,B
接不到,此次强测也是差点翻车了,不过三次做业笔者的总体结构仍是能够的,经过严格控制synchronized
语句块的分布与使用,三次做业除了这些bug也没有出现过死锁或是数据冒险啥的难以复现的bug1
,3
,15
是最特殊的3个换乘点,也能够枚举全部请求后排除直达请求进行换乘的完备hack第五次做业只创建了输入线程Din
,电梯线程Elev
,看到一些朋友把调度器也整成线程我是没想到的,Din
负责向Ctrl
输入数据,并在输入及结束后唤醒全部WAITING
的Elev
,Elev
的结束条件是没有待调度请求而且Din
在结束后设置了无输入的全局变量。具体调度策略方面,选用LOOK
算法,但不管SCAN
仍是LOOK
,都损失了一个方向上的请求信息,总感受不太好。因而以后笔者就真香GREEDY
了,打造了纯贪心的电梯调度与电梯间调度策略3d
第六次做业改动很少,主要是改变了Ctrl
中的数据结构适配多部电梯,另外的重头戏就是电梯间调度,笔者在本次将单电梯改成贪心电梯,与同窗交流中有的是用平均分配、随机分配来分派任务到各个电梯,但笔者仍是采用了电梯间自由地贪心竞争策略。缘由是,设想有两架Elev
,一台空载,一台载有乘客,从同一楼号出发,对于某一请求而言,载人Elev
由于电梯内请求而停靠或转向的平均几率更高,空载更有可能抢到请求。实际上载客越少越能直接相应电梯外请求,这有效减少某些电梯一直空转的概率,从而自动实现了优先级任务分配,提升了Elev
并行率,每次上一我的也能够Thread.sleep(5)
提升并行率。还有就是这样不用写二级调度了
第七次做业,鉴于要实现换乘,有必要维护须要换乘乘客的当前楼号,因而笔者新建了MyReq
类改进PersonRequst
,对于上文2、
中notify
了运行线程的bug,笔者也找到了安全方便的方案
for (int i = 0; i < elevNum; i++) { if (elevs.get(i).getState().equals(Thread.State.valueOf("WAITING"))) { synchronized (elevs.get(i)) { elevs.get(i).notifyAll(); } } }//先判断是在wait()再notifyAll();
同时要注意线程安全的坑,笔者是保证全部Elev
最后一块儿DEAD
的,防止要换乘的电梯早退
解决线程设计后,烦人的换乘问题来了,各型电梯的楼号定义域A = [-3, 1] ∪ [15, 20]
,B = [-2, 15] - {3}
,C = [1, 8] * 2 - 1
,找到换乘点(A ∩ B) ∪ (A ∩ C) ∪ (B ∩ C) = (C - {3}) ∪ {-1, -2}
,笔者并不想写二级调度,就创建了地址转换,考虑Elev
对MyReq
的解析,咱们只要在电梯A-C
下完成MyReq
在电梯内和在电梯外的楼号转换就行,实际上完成前者就行,若电梯内getToFloor()
非法,就将目的地改成换乘路径最短的换乘点。电梯外的话,先假设上电梯,转换后若目标就是当前楼层,就保留本来目的地,不然直接上电梯。笔者真是懒死了,这类特定情境问题仍是最好画图分析或打表,别像笔者败在细节。
笔者本单元的做业效果并不理想,仍是对于线程安全的理解不深,以及没有注重多线程程序设计中的细节问题致使bug,笔者仍是对本身的调度器耿耿于怀,笔者理应实现队列,调度分离的,这样的调度器耦合度过高了。