Unit Summary

 


 (Can't delete it...)



 

It's time for the unit summary.

The new three jobs are multi-threaded elevator scheduling, IFTTT, taxi scheduling

The following are the difficulties and challenges I encountered in the actual implementation process.

 


1. Multi-threaded scheduling

When I first came into contact with multi-threaded jobs, I was confused. What is multi-threading, what is thread safety, what is lock, how to lock, etc. These questions forced me to read related blogs to digest these concepts. First, the previous multi-threaded thread state diagram:

The various methods mentioned in the figure can be roughly divided into the following types according to the calling method

Thread methods: sleep, join, yield, etc.;

Object lock method: wait, notify, notifyAll;

Synchronization means: synchronized

The invocation of thread methods is mainly related to the allocation of system resources. For example, the sleep method makes the thread sleep and gives up system resources, so that other threads have more opportunities to be executed. The object lock method is mainly related to thread safety, ensuring that when multiple threads access a shared object, the execution result has nothing to do with the order of access of the threads. Among them, the difference between the sleep and wait methods is that the sleep method does not release the object lock, and the wait method releases the object lock and enters the "waiting pool" of the object to wait to be awakened. There is a blog post about the explanation of object locks that is very vivid, and I can't remember which one. . . But the general idea is as follows.

We can think of instantiated objects as an apartment building, object methods as rooms in the apartment building, and threads as people visiting the apartment building. Each apartment building has a unique lock on the door, which is shared by all rooms. Once a person has the lock of the apartment building, he can enter the apartment building and can go in and out of the rooms at will, during this time if another person visits the apartment building, because the lock is held by the other person, so the later People can only wait at the gate until the person holding the lock exits the apartment and informs others that the lock has been returned. From this, it is easier to understand the synchronized block. The synchronized block can be understood as a locked item in the room. If other people want to use the item, they must hold the lock. Unlocked items can be accessed freely.

The biggest difficulty encountered in this assignment is thread interaction. Thread interaction can be achieved through thread synchronization, so the difficulty lies in how to synchronize the three elevators and the scheduler. We need to realize that the elevator state does not change in one scan period, and make the movement of the three elevators as balanced as possible in the process of assigning tasks.

In order to ensure the principle of load balancing, the scheduler needs to know the basic information of each elevator. My previous approach was to directly access the objects of the three elevators in the scheduler, and the elevator objects obtained various information. However, this approach obviously makes the coupling between classes larger, the teacher provides another method, create a "release board", the elevator uploads its own status to the "release board", and the scheduler from the "release board" " to obtain the corresponding information. The second method clarifies the various functional responsibilities, and at the same time, it is easy to construct thread-safe classes.

There are other problems to be solved in this job. For each elevator thread, should it directly access the main queue, or create its own request queue? Details of the "Release Board" update and more. In short, the difficulty of this multi-threaded elevator scheduling is not increased by one or two steps, and it is very painful to do. . .

Homework BUG

The first time I tried multiple elevators, there were still quite a few bugs. The first is the homogeneous request. I realize the homogeneous judgment through the "lighting" system, that is, for a certain request, if the corresponding "light" has not been turned off at the moment of the request, the request is a homogeneous request. However, there was a problem in the specific implementation process, resulting in the synchronization request not being judged. Secondly, there is the allocation of requests, and there is no strategy for load balancing.

 

The cyclomatic complexity of the program and the depth of nested blocks are relatively large, and the number of lines of code in the analysis class can also be found, this time the design function distribution is not balanced, resulting in the scheduler code being too verbose, while the functions of some classes are relatively simple.


Second, IFTTT

 If the previous assignments are regarded as a "tear-hearted" episode with a progressive plot, this assignment is more like an "extra episode". . . The purpose of this work is also very clear: to further master the concept of threads and to strengthen the understanding of thread-safe design, the difficulty of the work is comparable to that of multi-threaded elevators. The requirement of the job is to realize the trigger task based on job monitoring. I am based on the following ideas.

The monitoring directory can be regarded as a collection of monitoring files, and the monitoring file is a special case of the monitoring directory. Therefore, the two have some common things, but also have their own characteristics. For example, for the monitoring file, if I set the monitoring scope as the current directory of the monitoring file, its search behavior is the same as the monitoring directory. Through snapshots, the changes of files within the monitoring range before and after are compared, thereby triggering corresponding tasks. The idea of ​​this job is extremely simple, but the specific implementation details are very many. . . We can give a concrete example.

There are three files A, B, and C with the same information except the file name in a certain path (this can be achieved by copying and pasting). We implement monitoring of file A, and trigger recovery operations when file A is renamed. Well, now we perform the following operations to delete file A, then theoretically the monitoring object should be lost and the trigger will not be responded. However, I estimate that some people's programs will use file B or C as a file with the same name as file A, so as to restore B or C (my program will do this...). The problem lies in the snapshot comparison. Only one-way inspection is performed, only the front-to-back comparison is performed, and the back-to-front comparison is not performed. When file A is deleted, we find that file A is missing in the latest snapshot. At this time, we searched for file information except for files B and C with different names. Then, we cannot immediately conclude that file B or C is a duplicate of file A. After naming the file, we can only draw this conclusion if the file B or C did not exist in the original snapshot.

In addition, when the monitoring object is a file, an additional detail needs to be paid attention to. Let's look at another example.

Only file A exists in a certain path. We implement monitoring of file A. When it is detected that file A is modified, the detailed information is recorded, the size of file A is changed, and the detailed information is recorded. File A is renamed and recorded. We do the following operations, first, change the last modification time of file A, then write content to file A, and finally rename file A to file B. In theory, all triggers should be triggered, but the result of actual operation is more likely to only detect that the file is modified and the file size is changed, and the file renaming is not triggered. One of the possible reasons is: when we change the last modification time of file A, the monitoring file stored by the program is still the original last modification time. There is a time inconsistency here. The consequence is that we are comparing the files. Because of the time difference between A and file B, the program thinks that file A has not been renamed. Therefore, after modifying the file, including the last modification time and file size changes, we need to update the properties of the monitored file in real time.

Homework BUG

The bug of this homework is basically in the situation I discussed above. The implementation of the details of this homework is really super many. If you are not careful, a certain bug will jump out. . .

 

 This work is mainly reflected in the cyclomatic complexity. The function of the InputHander class is to process the input to ensure the robustness of the program. Therefore, it is normal for the cyclomatic complexity to be high. Observing the number of class lines, it can be found that the job code this time has some progress compared to the last time, but the function in the monitor is relatively complex, and four kinds of triggers are integrated together.


 3. Taxi Scheduling

 I finally ushered in a relatively easy job. Although the number of threads in this job is a bit scary, I used the taxi as a thread and fixed it to 101 threads. I guess no one should use the request as a thread. The number of requests It's ok when it's relatively small, but it's exciting to think about starting 1,000 threads once there are 1,000 requests. . .

This job is similar to multi-threaded elevator scheduling, but it is much simpler to implement than multi-threaded elevators, mainly because it lacks the judgment of piggybacking requests. relatively simple. However, the requirements of this operation are relatively strict, and a lot of principles such as the "SOLID" principle, the principle of hierarchy, and the principle of balancing responsibility must be realized. . . The bug found in this assignment is an input check that doesn't take into account the presence of tabs. . . What I use here is the found bug, that is, I don't know if the program has functional bugs. . . All in all, this work is over very happily.

 Similarly, the cyclomatic complexity of this job is still reflected in the input processing class. The function of the Taxi class is more complex this time, almost rewriting the previous scheduler. . .


summary

In multi-threaded elevator scheduling and taxi scheduling, there are requirements for adjacent time differences. In terms of time-related requirements, I basically solve them through "simulation time". When checking the bug of the other party, the method of reading code + printout is adopted. . .

Finally, I hope the OO journey in the future will be easier.

 

Guess you like

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