Talk about the four classic applications of multithreading

Time:2020-2-27

Hello task, let’s meet again!! In the previous three simple articles, we have learned about the creation, operation, blocking, waiting, cancellation, delayed operation, asynchronous method and other related knowledge points of multithreading. Through these introductions, now we can write a multithreaded event in minutes. If you need to read the first three rows of articles, you can click the following link to quickly read thank you!

After talking about so many things, I think about it carefully, but I still want to have some practical project use cases. Now I’ll talk about how I usually use some commonly used business combing and processing in projects for reference. If it’s not easy to write, don’t spray. There’s a better solution. Welcome to exchange. Thank you!

 

Application 1. Taking and giving up in multithreading

 

Take the data of hotel rooms in the last few articles as an example to analyze. Suppose that the system connects the data of x-cheng, y-long and Q interfaces at the same time. When the user enters a hotel reservation page, the system needs to go to the third party in real time to get the real-time dynamic data of the corresponding room of the hotel and present it to the user. However, in this process, the user cannot wait too long, and It can provide as many channels as possible for users to choose, so how to achieve this demand at this time?

Students who have done aggregation platform, whether they are hotels, air tickets, consulting, etc., will encounter such similar business scenarios more or less. Let’s share how we usually achieve this.

In short, it’s a logic of fetching and discarding. You think, different interfaces have different query efficiency, and the same interface has different processing time at different times. In some special cases, it’s possible that an interface data needs to wait for 5-10S or even longer before fetching data. At this time, you can’t let users wait so long That’s right. It’s estimated that users are scared away. Moreover, waiting like this will bring a lot of pressure to the system, especially during the peak period of activities, which is a bottleneck of the system directly.

In order to achieve this goal, then in the implementation, we should first think about the interface that does not return data within the agreed time, then we will directly give up and only show the data that the user has obtained. How to realize it technically?

In terms of implementation, with task, everything becomes so easy, because the task. Wait method has taken such a scenario into consideration for us, which can be used directly.

Let’s take a look at some important aspects of task. WaitTake it.

    

See, in the overloaded method, there is a timeout field, which is used to discard the thread tasks that have not been completed due to timeout. How to use it? Go straight to the code!

    

static void Main(string[] args)
{
    Console. Writeline ("start getting hotel data...);
//Get the latest room information (assuming the maximum waiting time is 1s)
    List listHotelRoomInfro = GetHotelRoomInfro(1000);
    Console. Writeline ("after acquiring the hotel data, the acquired data is:");
foreach (var item in listHotelRoomInfro)
    {
        Console.WriteLine(item);
    }
    Console.ReadLine();
 }
 
/// 
///Get the latest room information
/// 
///Maximum acquisition time (i.e. abandonment time), in milliseconds
///Room information collection
private static List GetHotelRoomInfro(int maxWaitTimes)
 {
//Data collection of hotel rooms obtained by simulated storage
     List listHotelRoomInfro = new List();
//Here, I also use three different ways to realize three different channels
//First, instantiate a task object through the traditional new method to obtain the room data of Ctrip
     Task newCtripTask = new Task(() =>
    {
//Get business logic processing specifically
         Thread.Sleep(new Random().Next(100, 999));
        Listhotelroominfra. Add ("I'm the latest room information from Ctrip");
    });
//Start Tsak
     newCtripTask.Start();
//Second, generate a task object through the factory and start it automatically: obtain the room data of elong
     Task factoryElongTask = Task.Factory.StartNew(() =>
     {
//Get business logic processing specifically
         Thread.Sleep(new Random().Next(555, 1500));
         Listhotelroominfra. Add ("I'm the latest room information from elong");
     });
//Third, create a self starting task through task.run (action action): get the room data of qunar.com
     Task runQunarTask = Task.Run(() =>
     {
//Get business logic processing specifically
         Thread.Sleep(new Random().Next(1100, 2000));
         Listhotelroominfra. Add ("I'm the latest room information from qunari)";
     });
//Wait to get the interface and block the main process. If the interface side of maxwaittimes does not return data at the specified time, it will directly discard it
     Task.WaitAll(new Task[] { newCtripTask, factoryElongTask, runQunarTask }, maxWaitTimes);
return listHotelRoomInfro;
 }

 

Operation result:

Through the above operation results, we find that within 1s, only Ctrip returns the data, and then only the data of Ctrip is returned to the user. This example has been realized in this way. Of course, wi believes that you may have a better realization. Welcome to communicate and learn together. Thank you

 

Application 2: dynamic creation of multithreadingBatch processing

 

In actual projects, we will encounter the need to dynamically create multiple threads to optimize batch processing according to the number of tasks to be processed. Hahaha, isn’t it a little empty? It’s not urgent. Here’s a real scene. You can see it clearly.

Demand: take hotel data synchronization as an example. The specific requirements are as follows:

1. Manually select the designated hotels in batches, up to 500 hotels can be selected at a time

2. The system needs to synchronize the latest data of the interface side in the fastest way

Haha, do you think it’s very simple after seeing the demand? In two words, how to realize the demand?

You may say, simply, according to the hotel you chooseIt’s right to synchronize the data in a secondary queue! This is not good. If the user selects 500 hotels, assuming that the data synchronization of each hotel takes 2 seconds, then 500 pieces of data need 1000 seconds, and it will take nearly 20 minutes to finish processing. This is not the best time!

Then you also need to say that every hotel directly opens a thread to deal with it. Is that fast enough! Well, you’re right. The speed is going up. But if users choose 500 hotels, they need to create 500 threads, that is, 500 concurrent threads. What’s the problem? First, can you carry your own server? Second, if your server can carry it, what does the interface allow you to do? I’m afraid you’ve already been blacklisted. So this is not the best solution.

Ha ha, so much has been said, so how can it be realized? In fact, it’s also simple. I want to talk about a compromise between the above two schemes. Dynamically create reasonable threads according to multiple factors such as resources, and then process them in parallel. Come on, code it!

class Program
 {
     /// 
     ///The maximum number of threads allowed to be created can be configured through the configuration file
     ///The specific value should also be determined by multiple factors such as server resources + interface restrictions
     /// 
     public static int maxThread = 10;
     static void Main(string[] args)
     {
         //Suppose we choose to process 20 hotel data
         List listHotel = new List();
         for (int i = 0; i < 20; i++)
         {
             Listhotel. Add ($"this is the hotel {(I + 1). Tostring(). Padleft (2, '0')}");
         }

         //Create Tsak to process hotel data synchronization
         AsyncDynamicSynchronouslyHotel(listHotel);

         Console.ReadLine();
     }

     /// 
     ///Dynamically create Tsak to process hotel data synchronization according to the amount of hotel data
     /// 
     ///List of hotel data to be processed
     private static void AsyncDynamicSynchronouslyHotel(List listHotel)
     {
         object hotelTaskLock = new object();

         //Make a non empty judgment first
         if (listHotel == null || listHotel.Count < 1)
         {
             return;
         }

         //Task thread array
         List taskList = new List();

         //First, determine the threads to be opened according to the resource data amount + the maximum number of threads allowed
         int taskCount = listHotel.Count < maxThread ? listHotel.Count : maxThread;

         //Create specifies the number of task threads
         for (int i = 0; i < taskCount; i++)
         {
             //Create a task thread
             taskList.Add(new Task(() =>
             {
                 while (listHotel != null && listHotel.Count > 0)
                 {
                     //Assign a hotel processing task to this thread
                     string hotelInfro = string.Empty;

                     //Thread passing, add a resource lock
                     lock (hotelTaskLock)
                     {
                         //After obtaining the lock, we need to make a resource judgment to avoid the resource and consumption after obtaining the lock
                         if (listHotel != null && listHotel.Count > 0)
                         {
                             hotelInfro = listHotel[0];
                             listHotel.Remove(hotelInfro);
                         }
                     }

                     //Start to simulate real data synchronization operation
                     if (!string.IsNullOrEmpty(hotelInfro))
                     {
                         Thread.Sleep(1000);
                         Console. Writeline ($"this is thread ID {thread. Currentthread. Managedthreadid. Tostring()}, which completes the data synchronization of hotel [{hotelinfra}]");
                     }
                 }
             }));

             //Start thread
             taskList[i].Start();
         }
     }
 }

 

 

Operation result:

Set up to 5 threads

Set 10 threads to open

In this way, the automatic dynamic control of thread creation is achieved. Of course, this involves thread synchronization and other issues

 

Conclusion:

 

Through this article, I share with you the access and rejection of multi threads, dynamic creation of multi lines, etc. in the actual work process, or more or more, we will encounter such scenarios, hoping to be helpful

Well, I’m here today. If you have any questions, you can have more exchanges. Finally, I wish you a happy New Year’s day

Guess you like: 

Part 1: talk about multithreading, which is one of the tasks to create run and block

Part 2: talk about multithreading. Part 2: continuous operation

Part 3: talk about multithreading three asynchronous cancellation and asynchronous methods

Part 4: talk about multithreading: four classic applications (take and leave, dynamic creation)

END
In order to communicate more, you are welcome to pay attention to my official account.

Recommended Today

Laravel service container must know

The article was forwarded from the professional laravel developer community. Original link: https://learnku.com/laravel/t To learn how to build an application with laravel is not only to learn how to use different classes and components in the framework, but also to remember allartisanCommand or all helper functions (we have Google). Learning to code with laravel is […]