Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement java concurrent FutureTask

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

How to implement java concurrent FutureTask? in view of this problem, this article introduces the corresponding analysis and solution in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible method.

Overview

When using java multithreading to solve problems, in order to improve efficiency, we often deal with some computing tasks asynchronously and get the results asynchronously. The implementation of this process is inseparable from the Future interface and its implementation class FutureTask. The FutureTask class implements the Runnable and Future interfaces, and then I will explain the implementation of this class in detail through the source code.

Use

Let's first take a look at the main methods in FutureTask as follows, we can see that FutureTask implements the collection function of tasks and asynchronous results. When you see the method of this block, you will certainly have questions about how FutureTask relies on this method to get the result of thread asynchronous execution when the run method of Runnable task returns null. We will introduce this question to you below.

/ / implement the following five methods in interface Future: public boolean isCancelled (); public boolean isDone (); public boolean cancel (); public V get () throws InterruptedException, ExecutionException;public V get (long timeout, TimeUnit unit); / / implement method public void run () in interface Runnable

In use, we will construct a FutureTask object, and then throw the FutureTask into another thread for execution, while the main thread continues to execute other business logic, and after a period of time, the main thread calls the get method of FutureTask to get the execution result. Let's look at a simple example:

/ * Created by yuanqiongqiong on 2019/4/9.*/public class FutureTaskTest {private static ExecutorService executorService = Executors.newFixedThreadPool (1); public static void main (String [] args) {Callable callable = new AccCallable (1,2); FutureTask futureTask = new FutureTask (callable); executorService.execute (futureTask); System.out.println ("go to do other things in main thread"); try {Thread.sleep (1000);} catch (InterruptedException e) {e.printStackTrace ();} System.out.println ("go back in main thread") Try {int result = (int) futureTask.get (); System.out.println ("result is" + result);} catch (InterruptedException e) {e.printStackTrace ();} catch (ExecutionException e) {e.printStackTrace ();}} static class AccCallable implements Callable {private int a private int public AccCallable (int a, int b) {this.a = aittthis.b = b;} @ Overridepublic Integer call () throws Exception {System.out.println ("acc an and b in threadId =" + Thread.currentThread (). GetName ()) Return a + b;}

The output is as follows:

Go to do other things in main threadacc an and b in threadId = pool-1-thread-1go back in main threadresult is 3

Implementation analysis

Before analyzing the implementation, let's think about what we would do if we were asked to implement a function similar to FutureTask. Because you need to get the execution results, you need an Object object to store the execution results. The execution time of the task is uncontrollable, and we need a variable to represent the execution status. Other threads call the get method to get the results, blocking or suspending the thread when the timeout is not reached.

Therefore, a queue-like structure is needed to store information about threads waiting for the result, so that these blocked or suspended threads can be awakened after the task execution thread is completed to get the result. The actual implementation of FutureTask is a similar logic, as shown below.

First of all, take a look at the main member variables of FutureTask as follows:

/ / futureTask execution status private volatile int state;// specific execution task, the waiting thread node private volatile WaitNode waiters that uses callable.call () private Callable callable;// to execute the result private Object outcome; / / to get the result in the run method

For the execution status, there is a very clear explanation in the source code. Here I just post the source code, not explain it, as follows:

/ * Possible state transitions:* NEW-> COMPLETING-> NORMAL* NEW-> COMPLETING-> EXCEPTIONAL* NEW-> CANCELLED* NEW-> INTERRUPTING-> INTERRUPTED*/private static final int NEW = 0th private static final int COMPLETING = 1There private static final int NORMAL = 2There private static final int CANCELLED = 3There private static final int INTERRUPTING = 5th private static final int INTERRUPTED = 6

Then let's take a look at the constructor of FutureTask, as follows:

Public FutureTask (Callable callable) {if (callable = = null) throw new NullPointerException (); this.callable = callable;this.state = NEW; / / ensure visibility of callable} public FutureTask (Runnable runnable, V result) {/ / when the constructor is passed into the runnable object, the method of the static utility class Executors is converted into a callable object this.callable = Executors.callable (runnable, result); this.state = NEW; / / ensure visibility of callable}

As mentioned earlier, FutureTask's thread of execution calls its run () method to execute the task. Let's take a look at this logic:

Public void run () {/ / 1. If the execution status is not NEW or another thread executes the task, return if (state! = NEW | |! UNSAFE.compareAndSwapObject (this, runnerOffset,null, Thread.currentThread () return;try {Callable c = callable;//2. If the execution status is NEW, that is, the task has not been executed, call the callable.call () method directly to get the execution result if (c! = null & & state = = NEW) {V result;boolean ran;try {result = c.call (); ran = true;} catch (Throwable ex) {result = null;ran = false;//3. If an exception occurs, update status to EXCEPTIONAL and wake up the suspended thread setException (ex);} / / 4. If the result is returned successfully, calling the set method will set the outcome, change the status execution state, and wake up the suspended thread if (ran) set (result);}} finally {/ / runner must be non-null until state is settled to// prevent concurrent calls to run () runner = null;// state must be re-read after nulling runner to prevent// leaked interruptsint s = state;if (s > = INTERRUPTING) handlePossibleCancellationInterrupt (s);}}

Let's take a look at the implementation of the set function, specifically at the execution in 4:

Protected void set (V v) {/ / change the execution state to COMPLETINGif (UNSAFE.compareAndSwapInt (this, stateOffset, NEW, COMPLETING)) {/ / set the execution result outcome = v this / NORMAL / set the execution status to NORMALUNSAFE.putOrderedInt (this, stateOffset, NORMAL); / / final state// performs post-processing operations, specifically traversing the blocked list, deleting the linked list nodes, and waking up the threads associated with each node finishCompletion ();}}

The above is the logic done by the task execution thread, and the above logic also answers the question of how FutureTask gets the execution result. Let's take a look at the implementation logic when the user calls the get method to obtain the execution result. At this time, FutureTask may handle various states, such as non-execution, execution, completion, exception, and so on, as shown below:

Public V get (long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {if (unit = = null) throw new NullPointerException (); int s = execute awaitDone when the execution status of state;// is NEW or COMPLETING to join the thread in the waiting queue and suspend the thread if (s

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report