Object-Oriented Course Multithreading Summary

The fifth assignment - multi-thread elevator

Metric-based program structure analysis:

 

 

 

Design strategy analysis and experience:

This is the first time the author has come into contact with the concept of multithreading. After this assignment, the author's biggest experience is that if I didn't write this multi-threaded elevator, I'm afraid I can't really grasp the object-oriented thinking. The process is tortuous. Every time I feel that I am approaching the best design plan, but more problems can always be discussed, so I seek solutions step by step and polish the design ideas step by step. After the painful design, I started to write the code on Monday. Fortunately, the early efforts were not in vain, and I finally finished writing and started debugging on Tuesday . I was overwhelmed with joy when I saw the results displayed correctly on Tuesday night. For design ideas, I have a lot of ideas that I want to jot down.

First of all, when I first came into contact with multithreading, one of the questions I wanted to ask the most was probably what object should I open a thread for? After the thread is opened, what work should be done in it, and what data structure should be used to organize it? What is the interaction object? Where does the thread safety problem occur?

The author proposes to first analyze the causal relationship and the independence of the process. The purpose of opening a thread is to simulate the real world, and the real world is the product of causality. Take elevator scheduling as an example. The main work of the elevator is running. The main work of the scheduler is to take requests and schedule elevators according to the requests. The logical relationship is the elevator At the mercy of the scheduler. Because elevator operation and dispatcher allocating requests to elevators need to be carried out separately, a thread should be opened for each elevator, and a thread should be opened for the request simulator. Continuing the analysis, IO processing should be separate from the scheduler, that is, the scheduler is only responsible for seeing if new requests are added, and the request simulator for IO waiting for the input of the request should be another thread (because scheduling takes all the time In progress, and the request simulator may be blocked waiting for input), at this time, the scheduler and the request simulator can interact through the shared object of the request queue. At this time, you will find that after figuring out why these threads are opened, the work that each thread is responsible for is divided into various modules, and the next thing to do is to analyze the tasks of each module.

Request simulator thread: read in the request, judge the validity of the request, and put it into the request queue if it is valid.

Scheduler thread: A main queue is needed to keep track of all requests to be executed but not assigned to elevators. The following work needs to be done for each scheduling. 1. Query the newly added request of the request simulator from the request queue (if not, return empty). 2. Judge all homogeneous requests according to whether the floor lights are lit, and throw them out of the main queue if they are homogeneous. 3. According to the main request of each elevator and the current position of the elevator, determine the piggyback request and assign it to the corresponding elevator, and throw it out of the main queue if it can be assigned. 4. At this time, the remaining requests of the main queue are neither qualitative nor piggybacked, which means that the queue head needs to find an idle elevator to complete. At this time, if there is an idle elevator, the request will be sent to the idle elevator and upgraded to the main request of the elevator. At this time, the next scheduling should be performed immediately to determine whether the newly upgraded main request can carry the remaining ones in the main queue. request.

Elevator thread: It needs its own execution request queue (that is, the piggyback queue prepared by the scheduler for the elevator), and checks whether the floor needs to execute the request after every specified time sleep ends. After the main request is executed, check whether the piggyback queue is empty. If it is not empty, it means that there are ER requests. At this time, select the earliest generated ER request to upgrade to the main request (the elevator completes the upgrade of the main request by itself); if it is empty, it means all All requests to be executed have been executed, and the status is set to idle, indicating that the scheduler is seeking a main request (the scheduler needs to schedule a main request).

After these analyses are completed, the security of the shared object interaction is yet to be analyzed. Obviously the shared objects here are the request queue and the elevator. The request simulator writes to the request queue, and the scheduler reads the request queue. The elevator thread controls the state of the elevator, and the scheduler writes the elevator execution queue and the main request. Most importantly, these operations require locking and synchronization control. (When the author wrote it for the first time, I had no experience and did not add synchronized , which resulted in a two-hour bug of asynchronous reading and writing, and I was dizzy.)

After completing these analyses, the idea becomes very clear, and you can start coding .

In fact, looking back, these ideas are very normal, but why was it so hard to think at that time orz . It may be because the previous jobs were directly scheduled with process-oriented thinking, and the change of thinking takes time. It is also possible that the coordination framework is not clear enough, and the functions of each part cannot be disassembled, and then the functional analysis and synchronization analysis of each object can be performed.

Analyze the bug of your own program :

Because of the rigorous thinking and constant discussions with my friends in this assignment, no bugs were found in terms of architecture and functions . I can't help but sigh here, teamwork is really a very enjoyable thing.

Analyze bugs in other programs :

The bugs in the program I got this time are a bit smaller. In addition, the author made a lot of tricky test sets in order to test my program, and still found some problems. There is a problem with the judgment of the other party's homogeneity. There is a problem with the upgrade of the main request when piggybacking, and there is a problem with the judgment of the piggyback after the upgrade. The details and the thread synchronization still need more consideration. The author also read the code of the testee and found that there are problems with not considering the data boundary and so on.

 

The sixth assignment - IFTTT file management system

Metric-based program structure analysis:

 

 

 

Design strategy analysis and experience:

The idea of ​​this job is obviously clearer than the last time, and with a further understanding of multi-threading, it is theoretically better to complete. But in fact, this is one of the most difficult times in my opinion so far. This assignment only lasted three days for the author, but I spent almost a day and a half reading the instruction book, discussion forum and WeChat group. After all, the instructions in the instruction book are very vague, and it is easy to cause misunderstandings, such as what is the situation of the document. There is no need for tracking and the like. The author thinks that the workload of IFTTT is also very large when writing code, and there will be more problems while writing. These problems seem to be non-convergence. After writing the bug (crossed out) code, the debug experience is also the most painful one, because the author always has various crashes that report null points and use null pointers , so I got an experience, before using variables in the future In the code, it is judged whether the variable is null , which is more convenient for the location of the bug .

Analyze the bug of your own program :

The bugs this time are all related to the requirements of the guide book. There are two mistakes in the public test. The first one is to ignore the guide book's requirement of "opening up to 10 thread objects ", because the author considers that there may be 4 objects for one object . Triggers, each trigger will have 3 monitoring tasks, so at most 120 threads can be opened, and it directly counts to 120 . But this is very problematic. Counting 120 directly will lead to 120 threads for different objects . It should be counted directly for the object instead of 120. The second is that the content of the modified trigger output to the file has less size changes. Record, this is because I take it for granted that I only need to record the content that causes the trigger to change, but I forgot to output all the file information. The author has an ambiguous understanding of the output content required by the instruction book. Give a clear request. One wrong mutual test is related to the null point crash mentioned above .

Analyze bugs in other programs :

The code drawn this time is from a big guy. The content is very concise but the functions are basically complete. It is worth reading and learning carefully. A little regret is that there is no further tracking of the path-changed file. The author thinks that this is a guide book that is a little unclear. There is also an incomplete because there is no method to create a folder. I feel that this is also not emphasized in the guide book, but the public beta gives a bunch of test cases that need to create a new folder. I hope that the functional requirements will be written more clearly in the future guidebook. When looking for bugs , the author further expanded the test according to the requirements of the branch tree.

 

 

The seventh job - the first job of multi-threaded taxi scheduling

Metric-based program structure analysis:

 

 

Design strategy analysis and experience:

The taxi scheduling guide is relatively complete, and the overall framework of this job scheduling is a bit like elevator scheduling. The focus is on the implementation of taxi threads and controller threads.

The two controller classes, Controller and FlashController , are the core of scheduling. The former realizes the allocation of the best taxi to the request at the end of the window, and the latter realizes the continuous search for a suitable taxi queue for the request during the window period. The purpose of this design is to In order to realize the idea of ​​" high cohesion and low coupling " , the scheduling of both tasks takes time, and there is no logical waiting relationship, so two schedulers are enabled to implement the design. The Taxi class uses a state machine to implement state transitions and is responsible for running according to the rules after receiving passengers. The interaction between threads is embodied in the controller's control and allocation according to the state of the request queue and the state of the taxi, and the interaction of objects mainly occurs between the taxi, the request queue and the controller. Because the request queue is a class that plays the role of "Tray" in the interaction object, the methods in the request queue include the " put " method provided for the request simulator , and the " fetch " method provided for the controller , which involves data interaction, so The data structure of RequestQueue is organized by the thread-safe LinkedBlockingQueue to solve the security problem between thread interactions. In the Taxi class, it may happen that multiple requests are assigned to multiple Taxi , then askRequest(To determine whether the current taxi has a request to be executed) method and addReq (to assign the corresponding request to the corresponding taxi) method may be accessed by multiple Taxi objects at the same time. In order to ensure thread safety, these methods must be synchronized to ensure thread safety. . In the same way, other methods of the taxi class also need to be locked to ensure that only one object can be written at the same time, so as to avoid the metaphysical problem of inconsistent reading and writing when threads are concurrent. The candidate in the Request class is the set of taxis found within the time window that the request can respond to. Because adding and taking out will have thread safety issues, it must be locked.

Analyze the bug of your own program :

This time the program has no functional bugs , but the "explicit expression principle" of the design principle is deducted. The tester believes that the state of the taxi is not expressed explicitly by numbers, and it is recommended to use an enumeration type. What he said is not unreasonable, but the essence of enumeration types is also a digital expression, not to mention the author explained the meaning of each number in the code and comments, and in the process of using the code, the state is expressed in IDLE , TODST , WFS , TOSRC Yes, but the numbers are used directly when outputting to the document. The author thinks this is a bit more realistic.

class STATE{

static final int IDLE = 0; // stop state

static final int TODST = 1; // Send the passenger to the destination state

    static final int WFS = 2; // Wait for service status

static final int TOSRC = 3; // Go to the state of picking up passengers

}

Analyze bugs in other programs :

The program drawn this time is very interesting, and the testee opens a thread for each request. I think his consideration for this may be to strictly control the time window of 3s , but in fact, there is a great risk in doing so. First of all, his purpose may not be achieved, because the thread scheduling time of the JVM is not under our control. , and this will cause multiple requests to access the taxi status at the same time, which will cause the waiting time to be longer due to the excessive number of requests, and the most important thing is that so many threads are opened for requests, and there is no limit to the number of requests , my eclipse was directly crashed by him orz . The author entered 100 instructions at one time, and directly reported a crash with full heap and full memory , and then eclipse was basically stuck. There is also a problem with the output of the tested person, and the snapshot output at that time is not directly taken, which leads to a problem with the judgment and the position of the passenger. Another is that the public beta did not judge whether the request start and end points are the same.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325215451&siteId=291194637