1  What is? future pattern

     Future
The pattern is similar to what we send Ajax request , The request is asynchronous , Users don't have to wait all the time , You can do other things first , Wait for the request to get the data , Before you continue to do what you did before . Or it's like we cook , But there's no kitchenware , At this time, we placed an order online , The website will prompt you that the order has been accepted , But we don't have to wait for the kitchenware to come , During the waiting period , We can buy vegetables first , Finally, the kitchenware came to cook together .

    How to achieve this ?

   
first , client Future Send request to server , At the same time , The server does not return real data , He will return you a wrapper class FutureData, Then the server starts a thread to request real data RealData, Real data acquisition complete , Give client a notification , Or the client can block other threads and wait for the real resource to load .

    We define a data interface Data, No matter the real data RealData And packaging data FutureData All inherit this interface .
public interface Data { String getRequest(); }
    Let's take a look main method , It calls FutureClient To get the data you want RealData,RealData inherit Data Interface .
public class Main { public static void main(String[] args) throws
InterruptedException { FutureClient fc =new FutureClient(); Data data =
fc.request(" Request parameters "); System.out.println("data is " + data); System.out.println(
" Request sent successfully !"); System.out.println(" Do something else ..."); String result = data.getRequest();
System.out.println(result); } }  
    Then let's take a look FutureClient
How does it help us get data , So let's look at the top main Method fc.request(" Request parameters ") The data returned in is not real data , Returns a wrapper class , At the same time, it will start a new thread to get the real data .
public class FutureClient { public Data request(final String queryStr){ //1
I want a proxy object (Data The implementation class of the interface ) Return to the client who sent the request first , Tell him the request has been received , You can do other things final FutureData
futureData =new FutureData(); //2 Start a new thread , To load real data , Pass to this proxy object new Thread(new
Runnable() {@Override public void run() { //3 This new thread can slowly load real objects , It is then passed to the proxy object
RealDatarealData = new RealData(queryStr); futureData.setRealData(realData); }
}).start();return futureData; } }

      Let's take a look FutureData Implementation of , He will wait RealData Request completed , Then send out a notification to get the real data . Thus, in the main Method data.getRequest(); You can get the actual execution results , This method blocks thread execution , Because we see in the FutureData There are wait and notify, Only the real results are available , To get the results .
public class FutureData implements Data{ private RealData realData ; private
booleanisReady = false; public synchronized void setRealData(RealData realData)
{// If it's already loaded , Just go back if(isReady){ return; } // If not loaded , To load real objects this.realData =
realData;isReady = true; // Give notice notify(); } @Override public synchronized
String getRequest() {// If it's not loaded The program is stuck all the time while(!isReady){ try { wait(); } catch
(InterruptedException e) { e.printStackTrace(); } }// After loading, the data can be obtained directly return this.
realData.getRequest(); } }  
     Let's take a look RealData Implementation of , The realization of real data acquisition .
public class RealData implements Data{ private String result ; public RealData
(String queryStr){ System.out.println(" according to " + queryStr + " Request real data , This is a time-consuming operation .."
);try { Thread.sleep(5000); } catch (InterruptedException e) {
e.printStackTrace(); } System.out.println(" The operation is over , Get the results "); result = " Request real results "; }
@Override public String getRequest() { return result; } } The results are as follows :
Request real data according to request parameters , This is a time-consuming operation ..
Request sent successfully !
Do something else ...
The operation is over , Get the results
Get real results
2  JDK Self contained implementation class --FutureTask

Simulation code :
public class MyFutureTask { public static void main(String[] args) throws
InterruptedException, ExecutionException {long startTime = System.
currentTimeMillis(); Callable<RealData> myTask = new Callable<RealData>() {
@Override public RealData call() throws Exception { return new RealData(" Get real results "
); } }; FutureTask<RealData> task =new FutureTask<RealData>(myTask); new
Thread(task).start(); System.out.println(" Request sent successfully !"); System.out.println(
" Do something else ..."); Thread.sleep(2000); if (!task.isDone()) { // Is it finished System.out
.println(" Please wait for the result patiently ,"); } RealData realData = task.get(); System.out
.println(realData.getRequest()); } }
Analyze the code above ,

The acquisition of real data is encapsulated in Callable Of call Method .
@FunctionalInterface public interface Callable<V> { /** * Computes a result,
or throws an exception if unable to do so. * * @return computed result *
@throwsException if unable to compute a result */ V call() throws Exception; }
1) In general Callable and runnable difference :
(1)Callable The method of interface rewriting is call(),Runnable The method of interface rewriting is run()
(2)Callable Can return a value after the task is executed , also call Method can throw an exception ; and Runnable The task of cannot return a value ,run Method cannot throw an exception .

2) Create a FutureTask object , take Callable Pass in as a parameter , And then take this object as Runnable, As a parameter , Restart a thread .

FutureTask inherit RunnabelFuture,Ruannable inherit Runnable and Future, among Future The interface defines the following methods :

public class FutureTask<V> implements RunnableFuture<V> public interface
RunnableFuture<V> extends Runnable, Future<V>
    Here is Future Methods of interface definition

boolean cancel(boolean mayInterruptIfRunning); // Cancel execution , An exception will be thrown boolean
isCancelled(); // Determine whether to cancel boolean isDone(); // Judge whether the execution is completed V get() throws
InterruptedException, ExecutionException;// Get execution results , Will block the thread V get(long timeout,
TimeUnit unit) throws InterruptedException, ExecutionException,
TimeoutException; // Get execution results , The first parameter is time , The second is the unit of time ,
                                                                // If it is not successful at the specified time , Will throw out TimeoutException abnormal
3) We can see from the above method FutureTask At the same time inherited Runnable method , So there are run method , As you can see below run Method mainly calls the call method

public void run() { 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 { result
= c.call(); ran =true; } catch (Throwable ex) { result = null; ran = false;
setException(ex); }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
interrupts int s = state; if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s); } }
4) stay run The beginning of the method is judged state, that state What is it? ? as follows

/** * The run state of this task, initially NEW. The run state * transitions
to a terminal state only in methods set, * setException, and cancel. During
completion, state may take on * transient values of COMPLETING (while outcome
is being set) or * INTERRUPTING (only while interrupting the runner to satisfy a
* cancel(true)). Transitions from these intermediate to final * states use
cheaper ordered/lazy writes because values are unique * and cannot be further
modified. * * Possible state transitions: * NEW -> COMPLETING -> NORMAL *
NEW -> COMPLETING -> EXCEPTIONAL * NEW -> CANCELLED * NEW -> INTERRUPTING ->
INTERRUPTED */ private volatile int state; private static final int NEW = 0;
private static final intCOMPLETING = 1; private static final int NORMAL = 2;
private static final intEXCEPTIONAL = 3; private static final int CANCELLED = 4;
private static final intINTERRUPTING = 5; private static final int INTERRUPTED =
6;api The initial state of the task is NEW, When the result is presented COMPLETING state , It's instantaneous , When the caller interrupts , It is INTERRUPTING, It's also instantaneous .
NORMAL Successful implementation ,CANCELED Cancelled ,INTERRUPTTED Be interrupted ,EXCEPTIONAL abnormal . See the gray part above for state transition .
5)get method , Main call awaitDone method , Mainly waiting for the execution to complete , It will terminate if there is an exception or timeout .

public V get() throws InterruptedException, ExecutionException { int s = state;
if(s <= COMPLETING) s = awaitDone(false, 0L); return report(s); }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 (Thread.interrupted()) { removeWaiter(q); throw new
InterruptedException(); }int s = state; if (s > COMPLETING) { if (q != null) q.
thread= null; return s; } else if (s == COMPLETING) // cannot time out yet
Thread.yield(); else if (q == null) q = new WaitNode(); else if (!queued)
queued =UNSAFE.compareAndSwapObject(this, waitersOffset, q.next = waiters, q);
else if(timed) { nanos = deadline - System.nanoTime(); if (nanos <= 0L) {
removeWaiter(q);return state; } LockSupport.parkNanos(this, nanos); } else
LockSupport.park(this); } }
3 application

1) Parallel execution is required , When there are few tasks

2) Create database connection under high concurrency , We can create a connection through a thread , And put this connection into the Callable Of call Method ,

In this way, other threads call get Method to get the connection , Avoid creating multiple connection, Waste of resources

Technology
©2019-2020 Toolsou All rights reserved,
In the problem of target detection “ recall Recall”,“ Accuracy Precision”Linux Page replacement algorithm C Language implementation About wechat payment body( Product description ) Problems encountered stay Vue Use in Web Worker Calculate the working days of each month c++ Memory Pointer out of bounds detection mechanism _CrtMemBlockHeadeJavaScript Medium Call and Apply Remember once EventBus Project issues caused by memory leaks Hundreds of millions of locusts rarely collide Locusts want to be self driving Heroes Java Swing JList: List box components