Talking about callback

About the author: Hello everyone, I am Brother Smart, a former architect of ZTE and Meituan, and now the CTO of an Internet company.

Contact qq: 184480602, add me to the group, let’s learn together, make progress together, and fight against the cold winter of the Internet together

I believe that most students, like me, have been troubled by the following concepts for a long time:

  • What is callback (callback function)?
  • What are synchronous/asynchronous/blocking/non-blocking?

Today, let us talk about these things together.

Explanation of callback concept

This is a very common method call:

Generally speaking, the method() call takes a very short time, usually only a few milliseconds. But if method() involves disk IO internally or method() is simply a network call (network IO), it may be more time-consuming. As for how long it takes to be considered "time-consuming", it's not easy to define. In the current case, it may be understood as: the caller cannot bear the time it takes to get the final result.

The main thread must wait for the method to return the result before it can continue and finally respond to the client.

How to solve time-consuming operations? You may easily think of "asynchronous":

The "asynchronous" here refers to the narrow "starting a sub-thread". But the above pictureis not complete. Method() in the original code has a result:

There is a contradiction at this time: although the method is executed asynchronously, the main thread needs to obtain the return result of the method.

You may easily think of two options:

  • main() starts a loop by itself and keeps asking the method: is it OK, is it OK... until there is a result
  • main blocks and waits

Here we simply imagine two ways to obtain sub-thread results. Don’t delve into how to implement them first.

But in fact,the two methods are the same for the caller (main),it has to wait for the time-consuming operation of method The result cannot be received until it is completed, so that the subsequent do something later operation can be performed.

So a contradiction arises:

  • do something depends on method's result
  • But the method is very slow
  • And I want to do something as quickly as possible and return

A better way to handle it is:

Since do something depends on the result of method, then do something should be processed together with method, so I moved do something inside method.

The picture on the left seems to use an asynchronous thread, but due to the need to obtain asynchronous results, blocking wait occurs, and the effect of asynchronous is not maximized!

How to move do something into method? The easiest way is of course to "cut" the entire code of do something directly into the method. But since doing something may change and is uncertain, it is best not to hard-code it in the method. In order for method() to help us perform customized operations, method() must provide another input parameter:

callback() is specific, and only the caller knows what kind of processing is to be done, so it is best for the caller to specify the specific callback processing.

There is call and there is back, so it is called callback.

callbacks and design patterns

The callback pattern is very similar to the strategy pattern, but I personally think there are subtle differences, mainly due to the different focus.

This is the callback:

This is the strategy pattern:

In the strategy mode, the callee generally pre-defines several strategies to choose from, such as the thread pool rejection strategy. But we can also customize the rejection policy

If you want to say that the strategy mode can also callback, it barely makes sense... but the starting points of the two are different. But if you change the scene, you will find that the two are still fundamentally different. For example, cross-system callback:

Different from in-process method calls, inter-system calls require additional ip+port

At this time, it is generally unlikely that anyone will call it "strategy mode".

The same is true for the observer mode, which looks very similar to callback, but the starting point is somewhat different. The starting point of the observer pattern is to receive notifications when the event source changes, while callback is more like a compromised step split. Of course, again, if you think these essences are the same, then it’s okay to think so. There is no need to stick to the definition.

callback and IO model

Many people have also studied BIO, NIO, and AIO. AIO also has a callback mechanism, which defines a CompletionHandler interface:

When an I/O operation is completed, the operating system automatically calls back completed(). Therefore, using this mechanism we can pre-write the callback function:

In general, callbacks can be large or small. The macroscopic ones include callback functions within the JVM and the callback interfaces between systems. The microscopic ones include the callback mechanism of the operating system. Even talk shows have callbacks.

A little humor for everyone.

Reflection: callback and synchronization, asynchronous, blocking, non-blocking

We usually say that asynchronous can "increase processing speed", which means that while the sub-thread is processing time-consuming tasks, the main thread can continue to perform its own tasks, just like Professor Hua Luogeng's "boil water to make tea" theory.

It is undeniable that washing the tea cups while boiling water can indeed improve some efficiency (there is no dependence between the two), but making tea must wait until the water is boiled (there is a dependence). In other words, the key question is "whether you want to get the result" (there are dependencies). If you don't want the result, you can really return it directly, which is much faster. Incredible.

From this we can derive four concepts that confuse most beginners:

  • synchronous blocking
  • Synchronous non-blocking
  • IO multiplexing
  • Asynchronous non-blocking

The core of understanding these concepts lies in:How the caller obtains the result (active or passive), and the state of the caller when obtaining the result (blocking or non-blocking).

Synchronization and asynchronousness focus onMessage communication mechanism (synchronous communication/ asynchronous communication):

  • The so-called synchronization means that when issuing a *call*,the *call* will not return until the result is obtained. But once the call returns, you get the return value. In other words, the *caller* actively waits for the result of this *call*
  • Asynchronous is the opposite.*After the call* is issued, the call returns directly, so no result is returned. In other words, when an asynchronous procedure call is issued, the caller does not get the result immediately. But after the *call* is issued, the *callee* notifies the caller through status, notification, or through callback function< a i=5>Handle this call

Blocking and non-blocking focus onThe status of the program when waiting for the call result (message, return value):

  • A blocking call means that the current thread will be suspended before the call result is returned. The calling thread will only return after getting the result
  • A non-blocking call means that the call will not block the current thread until the result cannot be obtained immediately.

Back to the "asynchronous programming" that we usually think is "fast":

In factSynchronization and asynchronousness in the IO modeland what we call “synchronization and asynchronous” in daily development They are two different concepts, don’t confuse them. Take NIO as an example. Some blogs on the Internet will say that NIO is asynchronous and non-blocking, but in fact from the IO model, it is synchronous and non-blocking. Only AIO is truly asynchronous and non-blocking. Since we are not doing academic research, there is no need to make strict distinctions. As long as we can clearly distinguish several IO models, the default daily use of multi-threading scenarios is also called "asynchronous".

Finally, have any students seen this during daily development:

The third-party client provides both asynchronous calling and callback methods.

Based on the above statement, what scenarios are these two methods suitable for?

About the author: Hello everyone, I am Brother Smart, a former architect of ZTE and Meituan, and now the CTO of an Internet company.

Join the group, let’s learn together, make progress together, and fight the Internet winter together

Guess you like

Origin blog.csdn.net/smart_an/article/details/134918720