1, Runnable source code parsing

Take a look at the Runnable source code, very simple

How does it fulfill our multifarious needs and applications with so little content?

Create a thread using Runnable to parse the code.

Public static void main(String[] args) {new Thread(()->{system.out.println (" I am Runnable"); }).start(); }Copy the code

The only place where Runnable is used is when objects are passed, and all other places are used by threads, which in turn implements our Runnable. Therefore, Runbale can be understood as the object executing the code, and the execution process and operation of the Thread are controlled by threads. The source code of Thread can be viewed at —-.

2, Callable source code analysis

Callable’s source code, unlike Runnable, cannot be started directly by Thread. It also requires a Future class

Future source

The public interface Future<V> {/** cancel method is used to cancel a task, returning true on success and false on failure. The mayInterruptIfRunning parameter indicates whether ongoing tasks that have not completed are allowed to be canceled, and true indicates that ongoing tasks can be canceled. Whether mayInterruptIfRunning is true or false, this method must return false if the task is completed, or if you cancel the completed task. True if the task is executing and false if mayInterruptIfRunning is set to true. If the task has not yet been executed, true is always returned regardless of whether mayInterruptIfRunning is true or false. */ boolean cancel(boolean mayInterruptIfRunning); The /** isCancelled method indicates whether the task was cancelled successfully, or returns true if the task was cancelled before it completed normally. */ boolean isCancelled(); The isDone method indicates whether the task is complete, and returns true if it is; */ boolean isDone(); The /** get() method is used to get the result of the execution. This method blocks and does not return until the task is finished. */ V get() throws InterruptedException, ExecutionException; /** get(long timeout, TimeUnit unit) returns null if no result has been obtained within the specified time. */ V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }Copy the code

As can be seen from the above source code, cancel can cancel the task, isCancelled and isDone can verify whether the task has been cancelled. Get can obtain the return value, but it is an interface and cannot be used directly, so there is its implementation class FutureTask.

Take a look at who the FutureTask source code implements

public class FutureTask<V> implements RunnableFuture<V> {
Copy the code

You can see that there’s a new content, RunnableFuture, look at the content.

Constructor of FutureTask

    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

    public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }
Copy the code

Callabel code test

class ThreadCallabel implements Callable<String>{ @Override public String call() throws Exception { System.out.println(" call "); Return b. } public static void main(String[] args) throws ExecutionException, InterruptedException {// Obtain the execution object ThreadCallabel ThreadCallabel = new ThreadCallabel(); FutureTask<String> FutureTask = new FutureTask(threadCallabel); // execute new Thread(futureTask).start(); String result = futureTask.get(); System.out.println(result); }}Copy the code

output

Another way to do this is through the ExecutorService, as shown below

class ThreadCallabel implements Callable<String>{ @Override public String call() throws Exception { System.out.println(" call "); Return b. } public static void main(String[] args) throws ExecutionException, InterruptedException {/ / create the ExecutorService ExecutorService executor. = Executors newCachedThreadPool (); ThreadCallabel ThreadCallabel = new ThreadCallabel(); FutureTask<String> FutureTask = new FutureTask<String>(threadCallabel); / / execution executor. Submit (futureTask); // Release the resource executor.shutdown(); System.out.println(futureTask.get())); }}Copy the code

Execution result is the same

Thread and Runnable are contents of the java.lang package.

Callable, Future, FutrueTask, RunnableFutrue, Executors, and ExecutorService are all under the JUC (Java.util.Concurrent) package.

Executors are also a tool class for creating thread pools.

 
Copy the code