FutureTask yes future Implementation class of , It implements two interfaces at the same time :Runnable and Future, So it can be used as Runnable Executed by thread , It can also be used as Future obtain Callable Return value of .

So we can :
- call FutureTask Object's run() Method execution
- call FutureTask Object's get() Methods the results were obtained
- You can also FutureTask Object as callable Using thread pool or Thread Class to execute .

FutureTask Two important attributes are state ,runner .futureTask Why it can be supported cancel operation Because of these two attributes
among state by enum :
NEW newly build 0
COMPLETING In execution 1
NORMAL normal 2
EXCEPTIONAL abnormal 3
CANCELLED cancel 4
INTERRUPTING Interrupted 5
INTERRUNPED Interrupted 6

state There are four ways to change the state of
NEW->COMPLETING->NORMAL Normally completed process
NEW->COMPLETING->EXCEPTIONAL Process with exception
NEW->CANCELED Cancelled
NEW->INTERRUNPING->INTERRRUNPTED Interrupted

We use it FutureTask Rewrite the previous example :
public class FutureDemo { public static void main(String[] args) { /*
Defining producers : It's for making moon cakes Callable */ final Callable<Integer> callable = new
Callable<Integer>() {public Integer call() throws Exception { /* Simulate time-consuming operations , need 5 second */
Thread.sleep(5000); /* Return a box of moon cakes */ return new Random().nextInt(10000); } };
/* Start thread B-- consumer : Get moon cake */ Runnable runnable=new Runnable() { public void run() { try
{ ExecutorService tPool = Executors.newSingleThreadExecutor(); System.out
.println(" boss , Start making moon cakes for me ..."); /* Start thread A-- producer : Run time consuming operations , Production of moon cakes * Get a mooncake coupon at the same time CookTicket*/
//final Future<Integer> CookTicket = tPool.submit(callable);
FutureTask<Integer> CookTicket =new FutureTask<Integer>(callable);
tPool.submit(CookTicket);//CookTicket.run(); Another way to call //new
Thread(CookTicket).run(); Another way to call /* Get the moon cake */ System.out.println(
"5 Seconds later, exchange the mooncake coupon for the moon cake , The box of moon cake number :"+CookTicket.get()); System.out.println(" Take the cake home ..."); }
catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } }
};new Thread(runnable).start(); } }
FutureTask There is a way void done() Will be executed on each thread return Callback on result .
Now we need to implement each thread to execute the follow-up task after completing the task .
public class FutureDemo { public static void main(String[] args) { /*
Defining producers : It's for making moon cakes Callable */ final Callable<Integer> callable = new
Callable<Integer>() {public Integer call() throws Exception { /* Simulate time-consuming operations , need 5 second */
Thread.sleep(5000); /* Return a box of moon cakes */ return new Random().nextInt(10000); } };
/* Start thread B-- consumer : Get moon cake */ Runnable runnable = new Runnable() { public void run() {
System.out.println(" boss , Start making moon cakes for me ..."); /* Using cache thread pool to open multiple threads at the same time */ ExecutorService tPool
= Executors.newCachedThreadPool();/* Start thread A-- producer : Run time consuming operations , Three production lines start to produce moon cakes */ for(int i=0
;i<3;i++){ FutureTask<Integer> CookTicket = new FutureTask<Integer>(callable){
/* When a thread completes the task , Call back now done function , Carry out consumption task .*/ protected void done() { super.done(); try {
/*get() Is the method to extract the results */ System.out.println("5 Seconds later, exchange the mooncake coupon for the moon cake , The box of moon cake number :"+get()); } catch
(InterruptedException e) { e.printStackTrace(); }catch (ExecutionException e) {
e.printStackTrace(); } } }; tPool.submit(CookTicket);//new
Thread(CookTicket).run(); } } }; new Thread(runnable).start(); } }
FutureTask Ensure that tasks are executed only once in a highly concurrent environment

There's an example on the Internet , But what is said in the middle is not very clear . I sort it out again .

In many high concurrency environments , Often we only need to perform certain tasks only once . This usage scenario FutureTask You can do it . Take an example , Suppose you have a band key Connection pool for , When key In existence , That is, direct return key Corresponding object ; When key When it doesn't exist , The connection is created . For such an application scenario , The usual method is to use a Map Object to store key Corresponding relationship with connection pool , The typical code is shown below :
private Map<String, Connection> connectionPool = new HashMap<String,
Connection>();private ReentrantLock lock = new ReentrantLock(); public
ConnectiongetConnection(String key){ try{ lock.lock(); if
(connectionPool.containsKey(key)){return connectionPool.get(key); } else{ // establish
Connection Connection conn = createConnection(); connectionPool.put(key, conn);
return conn; } } finally{ lock.unlock(); } }

In the example above , We ensure thread safety in high concurrency environment by locking , It's also guaranteed connection Create only once , But at the expense of performance . change to the use of sth. ConcurrentHash In the case of , Lock operation can be almost avoided , Greatly improved performance .
private ConcurrentHashMap<String,Connection> connectionPool = new
ConcurrentHashMap<String,Connection>();public Connection getConnection(String
key){ Connection conn=connectionPool.get(key); if(conn!=null){ return conn; }
else { conn=createConnection(); Connection return_conn =
connectionPool.putIfAbsent(key,conn);// according to putIfAbsent To determine whether there is a thread preemptively inserted if
(return_conn!=null){ conn=return_conn; } } return conn; } // establish Connection private
ConnectioncreateConnection(){ return null; }
However, it may occur in the case of high concurrency Connection Phenomenon created many times .

Why? ? Because create Connection It's a time-consuming operation , Suppose multiple threads are flooding in getConnection method , All found out key The corresponding key does not exist , So all the incoming threads begin to execute
conn=createConnection()
, But in the end, only one thread can connection Insert into map in . But since then , Created by other threads connection It's not worth it , Waste system overhead .

At this time, the most important problem to be solved is when key When it doesn't exist , establish Connection The action of (conn=createConnection();
) Can be placed in connectionPool.putIfAbsent() After that , This is exactly what it is FutureTask Time to work , be based on ConcurrentHashMap and FutureTask The modification code is as follows :
private ConcurrentHashMap<String,FutureTask<Connection>>connectionPool = new
ConcurrentHashMap<String, FutureTask<Connection>>();public Connection
getConnection(String key) throws Exception{
FutureTask<Connection>connectionTask=connectionPool.get(key); if
(connectionTask!=null){ return connectionTask.get(); } else{
Callable<Connection> callable =new Callable<Connection>(){ @Override public
Connectioncall() throws Exception { // TODO Auto-generated method stub return
createConnection(); } }; FutureTask<Connection> newTask =new
FutureTask<Connection>(callable); connectionTask =
connectionPool.putIfAbsent(key, newTask);if(connectionTask==null){
connectionTask = newTask; connectionTask.run(); }return connectionTask.get(); }
}// establish Connection private Connection createConnection(){ return null; }

Technology
©2019-2020 Toolsou All rights reserved,
1190 Reverses the substring between each pair of parentheses leetcodemysql Joint index details You don't know ——HarmonyOS Create data mysql Library process Character recognition technology of vehicle license plate based on Neural Network A guess number of small games , use JavaScript realization Talking about uni-app Page value transfer problem pytorch of ResNet18( Yes cifar10 The accuracy of data classification is achieved 94%)C++ Method of detecting memory leak One is called “ Asking for the train ” A small village Finally got the train