Summary of Java multithreaded programming assignments

1. Summary of multi-threading knowledge

1. Thread synchronization

  There is not much to describe the knowledge about creating threads. Let's start with the main one, talk about thread synchronization. Like the process synchronization in the operating system, the thread also faces the problem of resource sharing. How to deal with the resource sharing of the thread is the most important part of using multithreading. In Java, the concept of locks is introduced to deal with the resource competition relationship between multiple threads. The object of the "lock" can be a block of code, a method, or an object. Once a part is locked, we say that part acquires the lock. Then among multiple threads in java, only the thread that owns the lock can run, and other threads cannot run. Conflicts can be avoided if we lock blocks of code competing for resources. In the process of using locks, synchronized() is usually used; it means that a certain part of the code block is locked. Then we also introduce the following, wait(), and notifyAll(), the usage of notify. For example, take a multi-threaded elevator as an example, the relationship between the input in a multi-threaded elevator and the 1 scheduler. We enter multiple instructions at the same time at a time, and we call these multiple instructions a temporary queue. Each time each input command is scheduled, and each input command is added to the total queue. Then when input is required, the scheduler cannot be run to access the input temporary queue, because multiple accesses will cause an input to be scheduled multiple times, and instructions cannot be written during scheduling, because multiple writes will cause replay. Write the previous input, and ignore the previous input. Take a look at the code:

while ( true ) {
             while ( this .sign!=0) {    // Indicates that the queue is not empty 
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace ();
                }
            }
            /**
                Indicates intermediate processing
           */ 
            sign =1; // used to mark 
            notifyAll();
        }    

2. Three homework analysis

2. Multi-thread elevator

  It is indeed very difficult to just come into contact with multi-threading, and I have no clue when I first got it. The final result is not very good, but after debug it feels much better. First look at the results of the JProfiler performance analysis.

Results of JProfiler profiling

 

The thread locked by the wait() method is shown in red, and the CPU is used the most in the input stage, and then the three elevators start scheduling after receiving the command. After the last input of END, the input thread ends, and the elevator has not finished executing. until the end of execution. There will also be scheduling when the input is divided into three stages, so the utilization rate of the processor is the highest, then three elevators are scheduled at the same time, and finally one elevator is scheduled. It can be seen that when three elevators are scheduled at the same time, the CPU The usage is much higher than when a single elevator is dispatched. Note that in addition to running threads, the scheduling between CPU processing threads also occupies the CPU.

class diagram relationship

  1. Thread class: Elevator_run; Input; Super_ride. Among them, Input represents the input thread class, and then Elevator_run represents the elevator running thread class, so three Elevator_run thread classes are created, and then the Super_ride thread class represents the scheduling thread class. Threads are parallel, but the threads between input and scheduling must have wait() and notify() relationships to prevent errors caused by data conflicts in the w_legal class. At the same time, the resource Elevator class is shared between the Super_ride class and the Elevator_run class, so Elevator_run cannot be called when Super_ride calls Elevator. Similarly, Super_ride cannot be called when Elevator_run calls Elevator, so use synchronized() in these two threads to achieve thread synchronization .
  2. Regarding the elevator class, I treat the elevator class as a separate class, including only the attributes and one method of the elevator, and then separate the elevator operation as a class, the Elevator_move class, which includes all elevator methods and time calculations. The Elevator class is passed in through the constructor in the Elevator_run thread, and an object of the Elevator_move class is newly constructed.
  3. Regarding the scheduling class, the scheduling method is not directly implemented in Super_ride. Similarly, I also wrote a class dedicated to scheduling, which only includes scheduling attributes and methods. When scheduling, first pass the elevators and instructions in Super_ride through the construction method, then instantiate a scheduler, and pass the elevators and temporary queues into the scheduler to get the queue of each elevator.

Timing Diagram Analysis

 

Metric analysis

3. File system

About IFTTT

 https://en.wikipedia.org/wiki/IFTTT , or, https://baike.baidu.com/item/ifttt/8378533?fr=aladdin , and IFTTT is also a very powerful app, you can go to Try it, https://ifttt.com/products .

Results of JProfiler profiling

Since there are not many test files for this test, the CPU usage is relatively low. It is obvious from the picture that I have a problem, that is, the files are not monitored all the time. I will explain later. An input will add a thread, that is, each file corresponds to a monitoring thread, which is used to monitor and change the file in real time. The reason why the thread ends is because, in my program, the monitoring file will only monitor one change, but the monitoring directory will monitor multiple changes. The reason is explained in the class diagram section. The reason for the need to create a thread when the CPU usage grows in the initial stage is mainly input.

Class Diagram Description

This time the class diagram is obviously more chaotic

  1. Regarding thread classes, there are mainly five thread classes: Modified, Path_changed, Renamed, Size_changed, and Test_thread. The first four threads will not start at the beginning. Only when a valid monitoring object is entered and the monitoring process will create a new monitoring thread. Then Test_thread is the thread for testing.
  2. Regarding the class of monitoring files, when monitoring files, if it is a monitoring directory, then every file change in the directory will trigger the monitor. After the files in the directory are changed, they must be monitored. The way I implement it is to first build a File_all class;
    class File_all {protected String name=null;
        protected long f_l=0; 
        protected long l_t=0; 
        protected String path=null;
    }

     Since the File method returns a pointer to a file, the return value will change when the path changes. Therefore, the function of File_all is to store the attributes of the file before the path change, which is used for comparison after the file changes. . So how do you get all the files in the entire directory? Of course using recursive search.

    class Test {
        
        protected void test(String fileDir, ArrayList<File_all> fileList) {
            // = new ArrayList<File_all>();
            File file = new File(fileDir);
            
            File[] files = file.listFiles(); // Get all files or folders in the directory 
            if (files == null ) { // If the directory is empty, exit directly 
                return ;
            }
            // Traverse, all files in the directory, save the file attributes 
            for (File f : files) {
                File_all tem_file = new File_all();
                if (f.isFile()) {
                    tem_file.file = f;
                    tem_file.name = f.getName();
                    tem_file.f_l = f.length();
                    tem_file.l_t = f.lastModified();
                    fileList.add(tem_file);
                } else if (f.isDirectory()) {
                    test(f.getAbsolutePath(),fileList);
                }
            }
            return ;
        }
    }

     

  3. We pass an ArrayList of File_all into the method test, and then we can call this method to get fileList, which is a dynamic array that stores all file attributes.
  4. So if two threads monitor the same file, will there be a problem of resource contention? The answer is yes, because it is assumed that thread 1 is monitoring the files under the A path, and monitoring is Renamed Then recover. Thread 2 also monitors the files in path A, and the monitoring is Modified Then details. Then thread 1 runs first, then before thread 1 recovers the files in path A, thread 2 will get the wrong result and find that There are no documents. The solution I adopted is to lock the file, but only the changes of the files in the SIze_changed and Renamed threads will be locked, so that when monitoring the same file, if there is Renamed, the operation will be completed. Only then will the next thread run.
  5. The realization of snapshot, without reading the instruction book carefully, completely according to my own ideas, there is no concept of snapshot, only know that it is necessary to compare the difference between the two files before and after, the comparison method, the pseudo code is as follows:
    if(file_2.isDirectory()) {
                chose = 0;
                ArrayList <File_all> FileList = new ArrayList<File_all>();   // Create a new FileList to store the old file 
                test_sc.test(obj_path,FileList);    // Recursively get the old file attributes and store 
                while ( true ) {
                    ArrayList <File_all> FileList2 = new ArrayList<File_all>();   // Create a new file 
                    test_sc.test(obj_path,FileList2);    // Recursively get new file attributes and store 
                    /**
                    various operations
                    */ 
                    FileList.clear();    // After various comparison operations, that is, after comparing the old and new files, clear the old and new files 
                    FileList2.clear();
                    test_sc.test(obj_path,FileList);     // Get the old file again, store the old file for later comparison 
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace ();
                    }
                }
            }

Timing Diagram Analysis

 

Metric analysis

 The results of the metric analysis show that the code is still vulnerable.

4. Taxi

Results of JProfiler profiling

For the taxi test, I used a one-time input of a large number of requests. Judging from several peaks of CPU operation, the first one is the beginning of the program, creating 100 taxi threads, it can be seen that the creation of threads is more CPU-intensive, and then each input, each input is more CPU-intensive, The reason is that each input or construction of a scheduling thread also needs to create multiple threads, which will greatly increase the operation of the CPU. There will be some smaller peaks in the middle, which are taxis running.

Class Diagram Analysis

  1. Thread class: In fact, there are only Scheduler and Taxi_move, and the Input among them was written before, the program was not used, forgot to change it, and did not delete it, and then it was reported as a design defect, …………, this is the time of submission The class diagram of , so Input is still in the Taxi_move thread, which is the thread that represents the operation of the taxi. There are 100 Taxi_move threads for 100 taxis. The Taxi_move thread is mainly the operation of the taxi. The Scheduler thread is a scheduler thread. When the thread is created in the Request class, a scheduling thread is created for each valid input. Within 3s, if there is a car to answer, then a scheduling is completed, and then by changing the taxi's attribute, the Taxi_move thread will make the taxi run in a certain way. So taxi is a competing resource for Taxi_move thread and Scheduler thread? Not exactly, because the scheduler will not schedule running cars, and Taxi_move will only schedule running cars.
  2. Call the GUI, how to display the taxi on the GUI? Of course, the location of the taxi is refreshed every time the taxi status changes.
  3. Regarding the shortest path, and the random path when the taxi is wandering, it is all in the taxi class. GUI.java provides a method for finding the shortest path. Maybe some students will use the distance method in the guiInfo class, but if you look carefully, D[][] is an attribute of the guiInfo class, then we can directly pass The pointbfs(root) method obtains the shortest path from any point to the root, and then stores the path in D[][], which will greatly reduce the calculation time of the shortest path. Students who use real time can do this, but they don't have to care too much about the fake time they use. Regarding random paths,
    while(true) {
                direction = ( int )(1+Math.random()*5);    // select a random location 
                if (direction==1 && this .location_x<79 && map_mess.graph[location][location_1]==1 ) {
                     this .location_x = this .location_x+1 ;
                     break ;
                }
                else if(direction==2 && this.location_x>0 && map_mess.graph[location][location_2]==1) {
                    this.location_x = this.location_x-1;
                    break;
                }
                else if(direction==3 && this.location_y>0 && map_mess.graph[location][location_3]==1) {
                    this.location_y = this.location_y-1;
                    break;
                }
                else if(direction==4 && this.location_y<79 && map_mess.graph[location][location_4]==1) {
                    this.location_y = this.location_y+1;
                    break;
                }
            }

     Since it is a connected graph, there is always a way to go.

Timing Diagram Analysis

It can be seen that the relationship between the various classes

Metric analysis

It's not very happy that the complexity of the first circle has passed, but this is actually fake. After many tests, I found the problem, the real situation is this:

However, the reason is that I was in a hurry, the first picture is that the cyclomatic complexity has not been fully tested yet.

3. Summary of the second assignment

Some thoughts on multi-thread programming

  1. Thread synchronization: I don't know if my idea is right, but since the multi-threaded elevator, I have been thinking this way. All resource competition is the relationship between producers and consumers. Of course, there will also be the same class playing two roles at the same time, and the analysis will be more complicated at this time.
  2. The running of the thread ends. In the multi-threaded elevator, I have not dealt with the end of the thread of the elevator. Because we use while(true) to run the thread in many cases, it is easy to cause this, so the necessary mark is still very important.

experience

  To be honest, I actually write every homework with the idea that as long as it is effective, the final writing is not particularly good. These three weeks have been really difficult. In the first week, I thought of a sentence: "No Pains, No Gains". Just grit your teeth again, and in the second week, I thought of a sentence "If one day, you feel that life is so difficult, then maybe the harvest this time will be very huge." In the second week, I was about to give up on my third homework. Life was so important. Later, I gritted my teeth and persevered, because I thought of a sentence, "In the future, you will definitely thank yourself for working so hard now." In these very difficult days, I can only live on these chicken soups. So I want to share with everyone, come and "done this bowl of chicken soup".

 

Guess you like

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