Java callable Future interface execution mechanism decryption __java

Source: Internet
Author: User
Tags static class throwable

In Java, the code in which we perform asynchronous tasks can be written in this way.


Executorservice Executorservice = Executors.newsinglethreadexecutor ();

        future<string> stringfuture = Executorservice.submit (()-> {
            System.out.println ("Hello, World");
            return "HelloWorld";
        };

        System.out.println (Stringfuture.getclass (). GetName ());
        System.out.println (Stringfuture.get ());

Pass in a callable interface object in the Submit method. Inside is the Java code that executes asynchronously. We can see the asynchronous execution of the task is very simple, print a line of words Hello, world. The HelloWorld string is then returned to the Future<t> interface object to accept execution results. When we execute the Stringfuture.get () method, if the asynchronous task is not finished. The thread where the Future.get () method is located is blocked.

As we normally do with a thread to execute, the result of execution is generally that it will not come. However, the callable interface and the future interface can be used to get the results of the finished thread execution.

So with such a question we go to see how the JDK's source code is implemented.

First line of code

Executorservice Executorservice = Executors.newsinglethreadexecutor ();
We can know that a thread pool was created. The exact code is like this.
Executorservice Newsinglethreadexecutor () {
    finalizabledelegatedexecutorservice
        (  Threadpoolexecutor (1, 1,
                                0L, Timeunit.  Milliseconds,
                                linkedblockingqueue<runnable> ()));
The executors class creates a new implementation class for the Executorservice interface.
The inheritance structure of the class is like this.
The implementation class for the newly created Executorservice interface mainly uses the Delegatedexecutorservice class. The class encapsulates an implementation class that encapsulates a executorservice interface.
Static ClassDelegatedexecutorserviceextendsAbstractexecutorservice {Private FinalExecutorservicee; Delegatedexecutorservice (Executorservice executor) {e= Executor; }Public voidExecute (Runnable command) {e. Execute (command); }Public voidShutdown () {e. Shutdown (); } PublicList<runnable> Shutdownnow () { returne. Shutdownnow (); }Public BooleanIsShutDown () { returne. IsShutDown (); }Public BooleanIsterminated () { returne. isterminated (); }Public BooleanAwaittermination (LongTimeout, timeunit unit)throwsinterruptedexception { returne. Awaittermination (timeout, unit); } PublicFuture<?> Submit (Runnable Task) { returne. submit (Task); } Public<T> future<t> Submit (callable<t> Task) { returne. submit (Task); } Public<T> future<t> Submit (Runnable task, T result) { returne. submit (task, result); } Public<T> list<future<t>> InvokeAll (collection<?extendscallable<t>> tasks)throwsinterruptedexception { returne. InvokeAll (tasks); } Public<T> list<future<t>> InvokeAll (collection<?extendscallable<t>> Tasks,LongTimeout, timeunit unit)throwsinterruptedexception { returne. InvokeAll (Tasks, timeout, unit); } Public<T> T invokeany (collection<?extendscallable<t>> tasks)throwsInterruptedexception, Executionexception { returne. Invokeany (tasks); } Public<T> T invokeany (collection<?extendscallable<t>> Tasks,LongTimeout, timeunit unit)throwsInterruptedexception, Executionexception, timeoutexception { returne. Invokeany (Tasks, timeout, unit); }
}
We can see that all of the method implementations of the class are all calling the implementation classes of the Executorservice interfaces that can be encapsulated internally.
Some readers may ask what class the class of the packaged interface is. This should be the Threadpoolexecutor class.
We can look at the integration diagram
The Thraedpoolexecutor class also inherits the Abstractexecutorservice class. That's a good analysis.
Next we analyze the following code.
After the author directly to the analysis of the content in the form of annotations written in the code next to
future<string> stringfuture = Executorservice.submit (()-> {
    System.  out. println (" Hello , World ");
     "HelloWorld";
});
<T> future<t> Submit (callable<t> Task) {
    null  NullPointerException ();
This is actually the new object for a Futuretask class.
The Futuretask class implements the Runnable,future<t> and runnablefuture<v> three interfaces, and the Futuretask class object returned after the description can
Use
    runnablefuture<t> ftask = newtaskfor (Task) as the implementation class of the Future<t> interface;
	The asynchronous code in the Callable<t> interface is invoked in this line of code.
	The Execute method receives the object of the Futuretask class as a parameter to execute. Let's go to the Execute () method to see
    execute (ftask);
     ftask;
}


We can see that the method is implemented in the Threadpoolexecutor class. Of course execute (Runnable R) This method is declared in the executor interface.
OK, let's go through the implementation of the Execute () method to analyze and analyze
Public voidExecute (Runnable command) {if(Command = =NULL)throw NewNullPointerException (); * * Proceed in 3 steps: * * 1.
     If fewer than corepoolsize threads are running, try to * start a new thread with the given command as its  * Task.
     The call to Addworker atomically checks runstate and * workercount, and I prevents false alarms that would add
     * Threads when it shouldn ' t, by returning false. * * 2.
     If a task can be successfully queued, then we still need * to double-check whether we should have added a thread * (because existing ones died since last checking) or that * the pool shut down since to this method. So we * recheck state and if necessary roll back the enqueuing if * stopped, or start a new thread if there are
     None. * * 3.  If We cannot queue task, then we try to add a new * thread.
     If it fails, we know we are shut down or saturated * and so reject the task. */intc =ctl. get ();if(Workercountof (c) <corepoolsize) {
	We point into this line of code, the other is too complex, the author here is not analyzed, because today's topic is not too relevant
         true) return
            ;
        ctl. Get ();
     workqueue. Offer (command)) {
        ctl. Get ();
         (! isrunning (Recheck) && Remove (command))
            reject (command);
         (workercountof (recheck) = = 0)
            addworker (nullfalse);
    }
     false))
        reject (command);

The formal parameter of this method is the object of the Futuretask class that was just new. Because it also implements the Runnable interface, so it can be passed
Private BooleanAddworker (Runnable Firsttask,BooleanCore) {retry: for(;;) {intc =ctl. get ();intrs = runstateof (c); Check If queue empty only if necessary.if(Rs >=SHUTDOWN&&! (rs = =SHUTDOWN&& Firsttask = =NULL&&!Workqueue. IsEmpty ()))Return false; for(;;) {intWC = Workercountof (c);if(WC >=CAPACITY|| WC >= (core?)corepoolsize:maximumpoolsize))Return false;if(Compareandincrementworkercount (c)) BreakRetry; c =ctl. get (); Re-read CTLif(Runstateof (c)!= RS)ContinueRetry; Else CAS failed due to workercount; Retry Inner Loop}}Booleanworkerstarted =false;Booleanworkeradded =false; Worker W =NULL;Try{w =NewWorker (Firsttask);FinalThread t = W.Thread;if(T!=NULL) {FinalReentrantlock Mainlock = This.Mainlock; Mainlock.lock ();Try{//Recheck while holding lock. Threadfactory failure or if//Shut down before lock acquired.intrs = runstateof (ctl. get ());if(Rs <SHUTDOWN|| (rs = =SHUTDOWN&& Firsttask = =NULL)) {if(T.isalive ())//PreCheck ' t is startablethrow NewIllegalthreadstateexception ();Workers. Add (W);ints =Workers. Size ();if(S >largestpoolsize)largestpoolsize= S; workeradded =true; }
            }finally{Mainlock.unlock (); }if(workeradded) {
		This line of code starts the thread code in the callable interface.
		Now that the thread is started, we are going to see how the Run method defined by the Runnable interface is implemented, and we go into the Futuretask class of the Run method implementation class to
                T.start ();
                true;
            }
    
        {(! workerstarted)
            addworkerfailed (w);
    }
     workerstarted;
}

Run () {
    (| |
        !) UNSAFE. Compareandswapobject (Thisrunneroffset,
                                     null, Thread.CurrentThread ()) return
        ;
     {
        callable;
        NEW) {V result;    
             ran;
            {
		This line of code invokes the call method of the callable interface implementation class. The resulting return value is returned to a result variable
		The following code sets this variable to the member variable outcome of the Futuretask object. Result
                = C.call ();
                true;
             (Throwable ex) {
                null;
                false;
                SetException (ex);
            }
             (RAN)
		This line of code sets the execution result of the call method of the callable interface to the outcome member variable of the Futuretask class object
		We can click to see how the
                Set (result) is implemented;
     {
        //runner must be non-null until ' settled to
        //prevent concurrent to run ()
         null;
        State must is re-read after nulling runner to prevent
        //leaked
        the state; interrupts >interrupting)
            handlepossiblecancellationinterrupt (s);
    }

Set (v V) {
    (UNSAFE. Compareandswapint (thisstateoffsetNEW)  completing)) {
	The result of the call method for the callable interface is placed on the outcome variable.
         = v;
        UNSAFE. Putorderedint (thisstateoffsetNORMAL); Final State
        finishcompletion ();
    }

Here we can see that the result of the execution is saved on the outcome member variable of the Futuretask class object.
Let's take a look at the Future<t> interface-defined get method
/**
 cancellationexception {@inheritDoc}
 *
  * Interruptedexception, executionexception {
    State;
     completing)
        s = Awaitdone (false, 0L);
	Found here there is a method of the show, click to look at
     the case (s);
}
@SuppressWarnings ("Unchecked")
V(executionexception {
We can find the value of the outcome member variable
    outcome;
     NORMAL
        )(V) x;
     cancelled
        )cancellationexception ();
     executionexception ((throwable) x);
}

To the end of this article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.