48-What is the difference between Callable and Runnable?

Why do we need Callable? The flaws of Runnable
Let’s take a look first, why do we need Callable? To answer this question, let's first take a look at what are the defects of the existing Runnable?

Can’t return a return value
. The first defect. For Runnable, it can’t return a return value, although other methods can be used, such as writing a log file in the Runnable method or modifying a shared object. To achieve the purpose of preserving the execution results of the thread, but this kind of problem-solving behavior has many twists and turns, which is a curve to save the country, and the efficiency is really not high.

In fact, when executing a child thread in many cases, we all hope to get the result of the executed task, that is, we need to get the return value, such as requesting the network, querying the database, etc. But Runnable cannot return a return value, which is its first very serious flaw.

Checked Exception cannot be thrown The
second flaw is that checked Exception cannot be thrown, as shown in the following code:

public class RunThrowException {
    
    
 
   /**
    * 普通方法内可以 throw 异常,并在方法签名上声明 throws
    */
   public void normalMethod() throws Exception {
    
    
       throw new IOException();
   }
 
   Runnable runnable = new Runnable() {
    
    
       /**
        *  run方法上无法声明 throws 异常,且run方法内无法 throw 出 checked Exception,除非使用try catch进行处理
        */
       @Override
       public void run() {
    
    
           try {
    
    
               throw new IOException();
           } catch (IOException e) {
    
    
               e.printStackTrace();
           }
       }
   }

In this code, there are two methods. The first method is a normal method called normalMethod. As you can see, there is throws Exception in its method signature, and a new method is also thrown in its method. IOException().

Then in the code below, we created a new Runnable object and rewritten its run method. We have no way to declare an exception on the method signature of the run method. At the same time, there is no way to throw a checked Exception in this run method, unless it is wrapped with try catch as shown in the code, but it cannot be done without try catch.

These are the two major flaws for Runnable.

Why is there such a defect

Why is there such a defect? Let's take a look at the definition of the Runnable interface:

public interface Runnable {
    
    
   public abstract void run();
}

The code is relatively short, Runnable is an interface, and there is only one method, called public abstract void run(). This method has stipulated that the return type of the run() method is void, and this method does not declare any exception to be thrown. Therefore, when implementing and rewriting this method, we can neither change the return value type nor the description of the exception thrown, because when implementing the method, the grammatical regulations do not allow these contents to be modified.

Looking back at the many codes in the previous section, there has never been a situation where a return value can be returned in the run method.

Why is Runnable designed like this

Let's think about it one more layer. Why does Java design it like this?

Assuming that the run() method can return a return value, or can throw an exception, it is of no avail, because we have no way to capture and process it in the outer layer. This is because the class that calls the run() method (such as the Thread class and the thread pool) is Java Provided directly, not written by us.

So even if it can have a return value, it is difficult for us to use this return value. If we really want to make up for these two shortcomings of Runnable, we can use the following remedy-use Callable.

Callable interface

Callable is an interface similar to Runnable. Both the class that implements the Callable interface and the class that implements the Runnable interface are tasks that can be executed by other threads. Let's take a look at the source code of Callable:

public interface Callable<V> {
    
    
     V call() throws Exception;
}

It can be seen that it is also an interface, and its call method has declared throws Exception, and there is a return value of V generic in front, which is very different from the previous Runnable. To implement the Callable interface, you must implement the call method. The return value of this method is generic V. If you put the result calculated in the call into this object, you can use the return value of the call method to get the execution result of the child thread. .

The difference between Callable and Runnable

Finally, summarize the differences between Callable and Runnable:

  • Method name, the execution method specified by Callable is call(), and the execution method specified by Runnable is run();
  • Return value, Callable's task has a return value after execution, and Runnable's task has no return value after execution;
  • Throw an exception, the call() method can throw an exception, but the run() method cannot throw a checked exception;
  • There is a Future class that cooperates with Callable. Through Future, you can understand the execution of the task, or cancel the execution of the task, and get the result of the task execution. These functions are not available to Runnable. Callable is more powerful than Runnable.

The content of this time. First introduced the two defects of Runnable, the first is that there is no return value, and the second is that the checked exception cannot be thrown; then, why there is such a defect, and why it is designed like this; then the Callable interface is analyzed , And compare and summarize the difference between Callable interface and Runnable interface.

Guess you like

Origin blog.csdn.net/Rinvay_Cui/article/details/111056514