OO第二次总结

从第五次作业开始,我们接触到了多线程程序设计。多线程能够提高程序运行的效率,但是也对编写代码时数据的同步提出了更高的要求。接下来我将在这里对第五到七次作业进行一个简单的总结。

设计策略

第五次作业中,我们需要将之前的单部电梯拓展为多线程电梯。这次作业主要的数据同步问题在于请求发生器和调度器对于请求队列的数据共享,我采用的方法是使用 BlockingQueue 来代替之前使用的线程不安全的队列,以实现安全的线程间数据共享。第六次作业中,我们需要实现一个线程安全的文件类,这一次作业我主要使用了 Lock 类来给线程加锁,以防止多个线程同时修改一个文件时产生冲突。第七次作业中关于线程安全的部分则与第五次作业类似,只要用 BlockingQueue 来安全地管理请求队列即可。

基于度量分析程序结构

第五次作业

类图

度量

Method metrics
method ev(G) iv(G) v(G)
multielevator.Elevator.addRequest(ElevatorRequest) 1.0 2.0 2.0
multielevator.Elevator.carriable(Request) 2.0 11.0 11.0
multielevator.Elevator.Elevator() 1.0 1.0 1.0
multielevator.Elevator.Elevator(int,Floor) 1.0 2.0 2.0
multielevator.Elevator.getFloor() 1.0 1.0 1.0
multielevator.Elevator.getRunAmount() 1.0 1.0 1.0
multielevator.Elevator.getState() 1.0 1.0 1.0
multielevator.Elevator.getTime() 1.0 1.0 1.0
multielevator.Elevator.move(int) 1.0 1.0 6.0
multielevator.Elevator.run() 10.0 40.0 53.0
multielevator.Elevator.setFloor(Floor) 1.0 1.0 1.0
multielevator.Elevator.toString() 1.0 1.0 1.0
multielevator.Elevator.waitUntil(long) 1.0 1.0 1.0
multielevator.ElevatorRequest.ElevatorRequest() 1.0 1.0 1.0
multielevator.ElevatorRequest.ElevatorRequest(int,int,int,String) 1.0 1.0 1.0
multielevator.ElevatorRequest.getFloor() 1.0 1.0 1.0
multielevator.ElevatorRequest.sameAs(Request) 2.0 2.0 3.0
multielevator.FenwickTree.add(int,int,long) 1.0 3.0 3.0
multielevator.FenwickTree.add(int,long) 1.0 1.0 2.0
multielevator.FenwickTree.FenwickTree() 1.0 1.0 1.0
multielevator.FenwickTree.FenwickTree(long[]) 1.0 2.0 2.0
multielevator.FenwickTree.getSize() 1.0 1.0 1.0
multielevator.FenwickTree.query(int) 1.0 1.0 2.0
multielevator.Floor.addRequest(FloorRequest) 1.0 4.0 4.0
multielevator.Floor.allocateElevator(FloorRequest) 1.0 8.0 10.0
multielevator.Floor.Floor(Elevator[]) 1.0 2.0 2.0
multielevator.Floor.peekRequest(State,int) 2.0 2.0 2.0
multielevator.Floor.pollRequest(State,int) 2.0 2.0 2.0
multielevator.Floor.run() 4.0 12.0 14.0
multielevator.FloorRequest.FloorRequest() 1.0 1.0 1.0
multielevator.FloorRequest.FloorRequest(State,int,int,String) 1.0 1.0 1.0
multielevator.FloorRequest.getDirection() 1.0 1.0 1.0
multielevator.FloorRequest.getFloor() 1.0 1.0 1.0
multielevator.FloorRequest.oldGetDirection() 1.0 1.0 2.0
multielevator.FloorRequest.sameAs(Request) 2.0 1.0 3.0
multielevator.InputProcessor.getBeginTime() 1.0 1.0 1.0
multielevator.InputProcessor.InputProcessor() 1.0 1.0 1.0
multielevator.InputProcessor.InputProcessor(String,int) 1.0 1.0 1.0
multielevator.InputProcessor.printIllegalRequest(String,long,String) 1.0 1.0 3.0
multielevator.InputProcessor.process() 3.0 4.0 5.0
multielevator.InputProcessor.processRequest(String,long) 16.0 16.0 20.0
multielevator.Main.main(String[]) 4.0 7.0 10.0
multielevator.MultiRequestHandler.MultiRequestHandler(LinkedBlockingDeque) 1.0 1.0 1.0
multielevator.MultiRequestHandler.run() 3.0 7.0 8.0
multielevator.Pair.getFirst() 1.0 1.0 1.0
multielevator.Pair.getSecond() 1.0 1.0 1.0
multielevator.Pair.Pair() 1.0 1.0 1.0
multielevator.Pair.Pair(T,int) 1.0 1.0 1.0
multielevator.Pair.setFirst(T) 1.0 1.0 1.0
multielevator.Pair.setSecond(int) 1.0 1.0 1.0
multielevator.Request.getAns() 1.0 1.0 1.0
multielevator.Request.getElevator() 1.0 1.0 1.0
multielevator.Request.getFloor() 1.0 1.0 1.0
multielevator.Request.getInput() 1.0 1.0 1.0
multielevator.Request.getOrder() 1.0 1.0 1.0
multielevator.Request.getTime() 1.0 1.0 1.0
multielevator.Request.printResult(String) 1.0 1.0 3.0
multielevator.Request.printSame() 1.0 1.0 3.0
multielevator.Request.Request() 1.0 1.0 1.0
multielevator.Request.Request(int,int,String) 1.0 1.0 1.0
multielevator.Request.sameAs(Request) 1.0 1.0 1.0
multielevator.Request.setAns(String) 1.0 1.0 1.0
multielevator.Request.setElevator(int) 1.0 1.0 1.0
multielevator.RequestHandler.getRequests() 1.0 1.0 1.0
multielevator.RequestHandler.handle() 1.0 8.0 8.0
multielevator.RequestHandler.move(Request,Elevator) 1.0 1.0 1.0
multielevator.RequestHandler.RequestHandler() 1.0 1.0 1.0
multielevator.RequestHandler.RequestHandler(Vector) 1.0 1.0 1.0
multielevator.RequestQueue.clear() 1.0 1.0 1.0
multielevator.RequestQueue.front() 1.0 1.0 1.0
multielevator.RequestQueue.isEmpty() 1.0 1.0 1.0
multielevator.RequestQueue.pop() 1.0 1.0 1.0
multielevator.RequestQueue.push(Request) 3.0 3.0 3.0
multielevator.RequestQueue.RequestQueue() 1.0 1.0 1.0
multielevator.SmartRequestHandler.checkSame(UnsafeQueue<pair>,int,FenwickTree,Request) 4.0 6.0 6.0
multielevator.SmartRequestHandler.handle() 12.0 35.0 48.0
multielevator.SmartRequestHandler.isOnWay(int,int,int,Request) 2.0 4.0 7.0
multielevator.SmartRequestHandler.modifyTimes(boolean,FenwickTree,int,int) 1.0 7.0 7.0
multielevator.SmartRequestHandler.SmartRequestHandler() 1.0 1.0 1.0
multielevator.SmartRequestHandler.SmartRequestHandler(Vector) 1.0 1.0 1.0
multielevator.UnsafeQueue.clear() 1.0 1.0 1.0
multielevator.UnsafeQueue.elementAt(int) 1.0 1.0 1.0
multielevator.UnsafeQueue.front() 1.0 1.0 1.0
multielevator.UnsafeQueue.isEmpty() 1.0 1.0 1.0
multielevator.UnsafeQueue.length() 1.0 1.0 1.0
multielevator.UnsafeQueue.pop() 1.0 1.0 1.0
multielevator.UnsafeQueue.push(E) 1.0 2.0 2.0
multielevator.UnsafeQueue.resize() 1.0 1.0 2.0
multielevator.UnsafeQueue.UnsafeQueue() 1.0 1.0 1.0
Total 145.0 256.0 316.0
Average 1.6292134831460674 2.8764044943820224 3.550561797752809
Class metrics
class OCavg WMC
multielevator.Elevator 4.3076923076923075 56.0
multielevator.ElevatorRequest 1.25 5.0
multielevator.FenwickTree 1.8333333333333333 11.0
multielevator.Floor 4.5 27.0
multielevator.FloorRequest 1.3333333333333333 8.0
multielevator.InputProcessor 4.166666666666667 25.0
multielevator.Main 5.0 5.0
multielevator.MultiRequestHandler 3.5 7.0
multielevator.Pair 1.0 6.0
multielevator.Request 1.0 13.0
multielevator.RequestHandler 2.0 10.0
multielevator.RequestQueue 1.3333333333333333 8.0
multielevator.SmartRequestHandler 7.0 56.0
multielevator.State   0.0
multielevator.UnsafeQueue 1.2222222222222223 11.0
Total   248.0
Average 2.7252747252747254 16.533333333333335
Package metrics
package v(G)avg v(G)tot
multielevator 3.550561797752809 316.0

设计原则

电梯类的 run 方法中出现了代码逻辑,今后应当避免这种情况。

第六次作业

类图

度量

Method metrics
method ev(G) iv(G) v(G)
ifttt.FileAttributes.FileAttributes(SafeFile) 1.0 1.0 1.0
ifttt.FileAttributes.getLastModified() 1.0 1.0 1.0
ifttt.FileAttributes.getLength() 1.0 1.0 1.0
ifttt.FileAttributes.getName() 1.0 1.0 1.0
ifttt.FileAttributes.getParentPath() 1.0 1.0 1.0
ifttt.FileAttributes.getPath() 1.0 1.0 1.0
ifttt.FileAttributes.isDirectory() 1.0 1.0 1.0
ifttt.FileAttributes.setName(String) 1.0 1.0 1.0
ifttt.FileAttributes.setParentPath(String) 1.0 1.0 1.0
ifttt.FileAttributes.setPath(String) 1.0 1.0 1.0
ifttt.InputProcessor.process(String) 4.0 7.0 11.0
ifttt.Main.main(String[]) 7.0 9.0 13.0
ifttt.RecordDetail.handle(FileAttributes,FileAttributes) 1.0 1.0 2.0
ifttt.RecordSummary.handle(FlipFlop) 1.0 4.0 5.0
ifttt.SafeFile.createNewFile() 1.0 1.0 2.0
ifttt.SafeFile.delete() 1.0 1.0 1.0
ifttt.SafeFile.exists() 1.0 1.0 1.0
ifttt.SafeFile.getAbsolutePath() 1.0 1.0 1.0
ifttt.SafeFile.getName() 1.0 1.0 1.0
ifttt.SafeFile.getParentFile() 1.0 1.0 1.0
ifttt.SafeFile.isDirectory() 1.0 1.0 1.0
ifttt.SafeFile.lastModified() 1.0 1.0 1.0
ifttt.SafeFile.length() 1.0 1.0 1.0
ifttt.SafeFile.list() 1.0 1.0 1.0
ifttt.SafeFile.mkdir() 1.0 1.0 1.0
ifttt.SafeFile.move(SafeFile) 1.0 1.0 1.0
ifttt.SafeFile.newSafeFile(SafeFile,String) 1.0 1.0 1.0
ifttt.SafeFile.newSafeFile(String) 2.0 2.0 2.0
ifttt.SafeFile.renameTo(SafeFile) 4.0 4.0 4.0
ifttt.SafeFile.SafeFile(String) 1.0 1.0 1.0
ifttt.SafeFile.setLastModified(long) 1.0 1.0 1.0
ifttt.SafeFile.writeString(String,boolean) 2.0 4.0 4.0
ifttt.Task.equals(Object) 3.0 3.0 5.0
ifttt.Task.getFilePath() 1.0 1.0 1.0
ifttt.Task.getSubFiles(SafeFile) 1.0 3.0 3.0
ifttt.Task.handleTask(FileAttributes,FileAttributes) 1.0 3.0 3.0
ifttt.Task.monitorModified() 5.0 8.0 8.0
ifttt.Task.monitorPathChanged() 8.0 9.0 12.0
ifttt.Task.monitorRenamed() 8.0 10.0 13.0
ifttt.Task.monitorSizeChanged() 5.0 10.0 10.0
ifttt.Task.pathChangedSafeFile(ArrayList,FileAttributes) 4.0 5.0 6.0
ifttt.Task.renamedSafeFile(ArrayList,FileAttributes) 3.0 3.0 4.0
ifttt.Task.run() 1.0 4.0 4.0
ifttt.Task.Task(String,FlipFlop,MonitorTask) 1.0 1.0 1.0
ifttt.Test.run() 1.0 2.0 3.0
Total 88.0 118.0 140.0
Average 1.9555555555555555 2.6222222222222222 3.111111111111111
Class metrics
class OCavg WMC
ifttt.FileAttributes 1.0 10.0
ifttt.FlipFlop   0.0
ifttt.InputProcessor 9.0 9.0
ifttt.Main 9.0 9.0
ifttt.MonitorTask   0.0
ifttt.RecordDetail 1.0 1.0
ifttt.RecordSummary 4.0 4.0
ifttt.SafeFile 1.2777777777777777 23.0
ifttt.Task 5.25 63.0
ifttt.Test 2.0 2.0
Total   121.0
Average 2.688888888888889 12.1
Package metrics
package v(G)avg v(G)tot
ifttt 3.111111111111111 140.0

设计原则

出现了部分重复代码。

第七次作业

类图

度量

Method metrics
method ev(G) iv(G) v(G)
taxi.Graph.addEdge(Vertex,Vertex) 1.0 1.0 1.0
taxi.Graph.addVertex(Vertex) 1.0 2.0 2.0
taxi.Graph.bfs(Vertex) 4.0 3.0 4.0
taxi.Graph.dfs(Vertex,HashSet) 2.0 2.0 3.0
taxi.Graph.getMinDistance(Vertex,Vertex) 1.0 3.0 3.0
taxi.Graph.getNeighbourVertices(Vertex) 1.0 1.0 1.0
taxi.Graph.getNextVertex(Vertex,Vertex) 1.0 3.0 3.0
taxi.Graph.Graph() 1.0 1.0 1.0
taxi.Graph.isConnected() 2.0 2.0 2.0
taxi.InputProcessor.processMap(String,int,Graph) 12.0 7.0 13.0
taxi.InputProcessor.ProcessRequest(String,Graph,int) 5.0 1.0 11.0
taxi.Main.main(String[]) 8.0 13.0 14.0
taxi.Request.equals(Object) 4.0 3.0 6.0
taxi.Request.getAvailableTaxis() 1.0 1.0 1.0
taxi.Request.getRequestTime() 1.0 1.0 1.0
taxi.Request.getRequestVertex() 1.0 1.0 1.0
taxi.Request.getTargetVertex() 1.0 1.0 1.0
taxi.Request.hashCode() 1.0 1.0 1.0
taxi.Request.printResult(String) 1.0 1.0 2.0
taxi.Request.Request(Vertex,Vertex,long,int) 1.0 1.0 2.0
taxi.Request.toString() 1.0 1.0 1.0
taxi.RequestHandler.addRequest(Request) 3.0 3.0 4.0
taxi.RequestHandler.RequestHandler(ArrayList,Graph,TaxiGUI) 1.0 1.0 1.0
taxi.RequestHandler.run() 1.0 2.0 2.0
taxi.RequestHandler.updateRequests() 5.0 14.0 15.0
taxi.Taxi.getCredit() 1.0 1.0 1.0
taxi.Taxi.getId() 1.0 1.0 1.0
taxi.Taxi.getNowVertex() 1.0 1.0 1.0
taxi.Taxi.getState() 1.0 1.0 1.0
taxi.Taxi.getStatusTaxi(State) 1.0 3.0 3.0
taxi.Taxi.getTaxiStatus() 1.0 1.0 1.0
taxi.Taxi.increaseCredit(int) 1.0 1.0 1.0
taxi.Taxi.receiving() 2.0 2.0 2.0
taxi.Taxi.run() 2.0 3.0 6.0
taxi.Taxi.servicing() 2.0 2.0 2.0
taxi.Taxi.setRequest(Request) 1.0 1.0 1.0
taxi.Taxi.setTaxis(ArrayList) 1.0 1.0 1.0
taxi.Taxi.sleepAndUpdate(long) 2.0 2.0 3.0
taxi.Taxi.statusId() 5.0 2.0 5.0
taxi.Taxi.stopping() 1.0 1.0 1.0
taxi.Taxi.Taxi(Graph,int,TaxiGUI) 1.0 1.0 1.0
taxi.Taxi.waiting() 4.0 2.0 4.0
taxi.TaxiStatus.getCoordinateX() 1.0 1.0 1.0
taxi.TaxiStatus.getCoordinateY() 1.0 1.0 1.0
taxi.TaxiStatus.getQueryTime() 1.0 1.0 1.0
taxi.TaxiStatus.getState() 1.0 1.0 1.0
taxi.TaxiStatus.TaxiStatus(long,int,int,State) 1.0 1.0 1.0
taxi.Vertex.equals(Object) 4.0 1.0 6.0
taxi.Vertex.getNeighbourVertices() 1.0 1.0 1.0
taxi.Vertex.getX() 1.0 1.0 1.0
taxi.Vertex.getY() 1.0 1.0 1.0
taxi.Vertex.hashCode() 1.0 1.0 1.0
taxi.Vertex.setNeighbourVertex(Vertex) 1.0 1.0 1.0
taxi.Vertex.Vertex(int,int,Graph) 1.0 1.0 1.0
Total 104.0 108.0 148.0
Average 1.9259259259259258 2.0 2.740740740740741
Class metrics
class OCavg WMC
taxi.Graph 2.2222222222222223 20.0
taxi.InputProcessor 8.5 17.0
taxi.Main 12.0 12.0
taxi.Request 1.3333333333333333 12.0
taxi.RequestHandler 4.75 19.0
taxi.State   0.0
taxi.Taxi 2.0 34.0
taxi.TaxiStatus 1.0 5.0
taxi.Vertex 1.4285714285714286 10.0
Total   129.0
Average 2.388888888888889 14.333333333333334
Package metrics
package v(G)avg v(G)tot
taxi 2.740740740740741 148.0

设计原则

自我感觉没有问题。

Bug分析

第五次作业主要的 bug 是,对于同一时间输入的请求没有处理好,导致后输入的请求先响应。第六次作业主要的 bug 是,监控目录时,只要检测到一个文件发生变化就退出循环并更新快照,这是一个非常低级的算法错误。第七次作业未被报 bug,但是实际上 map.txt 不存在时,我的代码会出现错误。可以看到,这些 bug 与多线程没有什么关系。

这几次作业我没有发现别人的 bug。在进行测试时,我主要是通过阅读被测者的代码来相应地构造测试数据。

心得体会

完成这三次有关多线程的作业之后,我对 java 的线程机制有了较为深刻的理解,也基本学会了如何写出线程安全的 java 程序。在第七次作业中实现设计原则的时候,我深切地感受到了这些设计原则的重要意义,它能够让我们的代码可读性和可移植性更强,减小代码出错的几率。

原文地址:https://www.cnblogs.com/zhong-zihao/p/8981499.html