当前位置:网站首页>Future usage details

Future usage details

2022-04-23 17:36:00 Flechazo`

Future Usage details

Preface

Why does it appear Future Mechanism

Two common ways to create threads . One is direct inheritance Thread, The other is to realize Runnable Interface .

One drawback of both approaches is that : Unable to get execution result after task execution .

from Java 1.5 Start , Provided. Callable and Future, Through them, you can get the task execution result after the task execution .

Future The core idea of the pattern is to enable the main thread to use the time that it needs to wait synchronously to do other things .

Because the execution results can be obtained asynchronously , So you don't have to wait synchronously to get the execution result .

Future Usage details

It's easy to use

	  	System.out.println(" main start ");
        FutureTask<Integer> integerFutureTask = new FutureTask<>(new TestA());


        new Thread(integerFutureTask).start();
        System.out.println(" integerFutureTask ...");
        Integer integer = integerFutureTask.get();
        System.out.println(integer);
        System.out.println(" main end ");

class TestA implements Callable<Integer>{
    

    @Override
    public Integer call() throws Exception {
    
       System.out.println(" call start ");
        Thread.sleep(10000);
        System.out.println(" call end ");
        return 1;
    }
}

get It will always block access

 Insert picture description here

Of course, you can also set the timeout

public V get(long timeout, TimeUnit unit)

Future Simple principle

It's simple to use , Let's study the specific principle

We all know Thread Can only run Runable Interface

How does the return value return ?

FutureTask<Integer> integerFutureTask = new FutureTask<>(new TestA()); In this line of code, you can see FutureTask Realized RunnableFuture Interface

 Insert picture description here
Continue to look at RunnableFuture The interface inherits our Runnable Interface And inherited a Future Interface
 Insert picture description here
Future Interface
Defines some methods that return values

public interface Future<V> {
    

// Cancel 
    boolean cancel(boolean mayInterruptIfRunning);

  // Whether to cancel 
    boolean isCancelled();

  // Whether to carry out 
    boolean isDone();

    //  obtain 
    V get() throws InterruptedException, ExecutionException;

// Timeout to get 
  
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

The principle and process are as follows

First step
 Insert picture description here

Initialization task , Set thread state

We can see several states of the thread and some states from start to end

 Insert picture description here

outcome Is the return value of the output
runner Indicates the running thread
waiters Indicates the waiting thread

The second step

run Method run

    public void run() {
    
    	// Determine whether it is running  
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
    
        	//
            Callable<V> c = callable;
            if (c != null && state == NEW) {
    
                V result;
                boolean ran;
                try {
    
                	// actual   The bottom layer is still running call Interface 
                    result = c.call();
                    // Running state 
                    ran = true;
                } catch (Throwable ex) {
    
                    result = null;
                    ran = false;
                    // Handling exceptions 
                    setException(ex);
                }
                if (ran)
                //c.call()  At the end of the run , Set result  
                    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 interrupts
            int s = state;
            // If the thread is interrupted  
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }

The setting result sets the thread state to , Also set the value outcome

 Insert picture description here

Third parts
get To get the results

 Insert picture description here
You can see that when the state is not greater than or equal to COMPLETING It will block

private int awaitDone(boolean timed, long nanos)
        throws InterruptedException {
    
        final long deadline = timed ? System.nanoTime() + nanos : 0L;
        WaitNode q = null;
        boolean queued = false;
        for (;;) {
    
        // If the thread is interrupted  
            if (Thread.interrupted()) {
    
            // Waiting to be removed from the queue 
                removeWaiter(q);
                throw new InterruptedException();
            }

            int s = state;
            // Execution completed 
            if (s > COMPLETING) {
    
           
                if (q != null)
                    q.thread = null;
                return s;
            }
            else if (s == COMPLETING) // cannot time out yet
            // hand over cpu Executive power   Re competition 
                Thread.yield();
            else if (q == null)
                q = new WaitNode();
            else if (!queued)
            // Next thread   Wake up the 
                queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                     q.next = waiters, q);
            else if (timed) {
    
            // Overtime 
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L) {
    
                    removeWaiter(q);
                    return state;
                }
                LockSupport.parkNanos(this, nanos);
            }
            else
                LockSupport.park(this);
        }
    }

Return value Strong transition type

 Insert picture description here

Thread pool return principle

Submit a return task with parameters
 Insert picture description here

Submission code
 Similarly, we know that a single is returned in this way , that

Also to FutureTask To carry out
 Insert picture description here

Custom return task value

You can refer to this to implement your own submission

Get data interface

public interface Future<T> {
    

    T get() throws InterruptedException;
}

Do things interface

public interface FutureTask<T> {
    

    T call();
}

Submit processing tasks asynchronously

public class FutureTaskService {
    

    /** *  Submit processing tasks asynchronously  * @param futureTask * @param <T> * @return */
    public <T> Future<T> submit(final FutureTask<T> futureTask){
    

        // Asynchronous return 
        AysFutureTask<T> aysFutureTask = new AysFutureTask();

        // Threads handle tasks 
        new Thread(()->{
    
            // Perform tasks 
            T call = futureTask.call();
            // Finish the task   Notification return 
            aysFutureTask.done(call);

        }).start();

        // Asynchronous return 
        return aysFutureTask;
    }

}

test

public class MainTest {
    

    public static void main(String[] args) throws InterruptedException {
    

        FutureTaskService futureTaskService = new FutureTaskService();
        Future<String> submit = futureTaskService.submit(() -> {
    
            // Submit tasks 
            return doThing();
        });


        System.out.println(" --------  return  ------- ");
        System.out.println(" ---------  Do something else  ----- ");
        System.out.println(" --------- do other ----- ");
        // obtain   The task just submitted 
        System.out.println(submit.get());


    }


    /** *  Simulate database reading and writing   perhaps   Network request  * @return */
    private static String doThing(){
    

        try {
    
            Thread.sleep(5_000);
        } catch (InterruptedException e) {
    
            e.printStackTrace();
        }

        return "  Do things ...";
    }
}

test result

 Insert picture description here
You can see the task we submitted first , Get the results after handling other things in front , During this period, the task is being carried out , Perform multiple tasks at the same time , Blocking the results at the last moment .

Last

FutureTask yes Future The concrete realization of .

FutureTask Realized RunnableFuture Interface .RunnableFuture The interface also inherits Future and Runnable Interface .

Thread You can submit FutureTask It's actually execution call Method
And then use cas Compare thread status and wait for results

Future Inheritance graph
 Insert picture description here

Of course Future There are other extended uses , Such as CompletableFuture etc.

版权声明
本文为[Flechazo`]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231727205353.html