Use of Future pattern in Java

Posted by pmeasham on Sun, 24 Oct 2021 17:07:02 +0200

preface

Today is 1024. I wish all bosses a happy holiday!

I'm going to go downstairs to buy some food in the evening. I'm determined to pay attention. I'm going to buy [egg] and [hand grasping cake] tonight. Good guy, there's no material. Hey, hey!

So I set out with the pace of "six relatives do not recognize"

Can you hurry up

❓ On the way, I thought about a problem. That is, how long does it take me to grasp simple happiness?

According to the process, it's like this

1. Ride my beloved little motorcycle
2. Arrive at the egg stall, order an egg, and wait for the boss to finish
3. Then go to the hand cake stall and order a hand cake
4. Grab the cake and ride home

Suppose the round trip is 6 minutes, the time for making eggs is 10 minutes, and the time for making hand grabbing cakes is 5 minutes

Then I need a total of [21] minutes before I can sit by the computer, watch a play and cook

If you want to shorten the time, the above process is not what we need, but should be like this

1. Ride my beloved little motorcycle
2. Arrive at the egg stall, order an egg and tell the boss I'll get it later
3. Then go to the hand cake stall and order a hand cake
4. After getting the cake, return to the egg stall and wait for the egg
5. go home by bicycle

At this time, our time is only [16] minutes, because this time after I ordered the eggs, the boss first completed an operation that took less than 10 minutes during the cooking period, that is, to buy the hand grabbing cake I want

Of course, I must use the second way...

Land

Sort out the process just now

• The first process is typical, which is executed in sequence
• The second process uses the idea of asynchrony

Then you might as well knock down the code and show the process

First, we have to have someone to buy food

```/**
* @Author: Amg
* @Date: Created in 20:22 2021/10/24
* @Description: Construct "buy something to eat" object
*/

/**
* Food name
*/
private String foodName;
/**
* Production duration unit
*/
private TimeUnit unit;
/**
* Production time
*/
private Long waitSecond;

public BuySomethingToEat(String foodName, TimeUnit unit, Long waitSecond) {
this.foodName = foodName;
this.unit = unit;
this.waitSecond = waitSecond;
}

@Override
public String toString() {
return new StringJoiner(", ", BuySomethingToEat.class.getSimpleName() + "[", "]")
.toString();
}
/**
* Processing ingredients
* @return
*/
public String handlerFood() {
System.out.println(String.format("Food is being prepared:[%s],Company:[%s],Waiting time:[%s] ",foodName,waitSecond,unit.toString()));
try {
unit.sleep(waitSecond);
} catch (InterruptedException e) {
e.printStackTrace();
}
return this.toString() + " is done!";
}
}
```

```/**
* @Author: Amg
* @Date: Created in 21:09 2021/10/24
* @Description: Conventional practice
*/
public class Convention {

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

final long start = System.currentTimeMillis();
//We can't have time to really wait for 10 minutes, so we use seconds instead

System.out.println(eatOne.handlerFood());
System.out.println(eatTwo.handlerFood());

System.out.println("I bought it all,Go home!");
//Finally, add six minutes back and forth
System.out.println("Total time:" + ((System.currentTimeMillis() - start) / 1000 + 6));

}
}
//output
Food is being prepared:[egg puffs],Company:[10],Waiting time:[SECONDS]
BuySomethingToEat[foodName='egg puffs', unit=SECONDS, waitSecond=10] is done!
Food is being prepared:[shredded pancake],Company:[5],Waiting time:[SECONDS]
BuySomethingToEat[foodName='shredded pancake', unit=SECONDS, waitSecond=5] is done!
I bought it all,Go home!
Total time: 15
```

Execute according to the idea of asynchrony

Asynchronous thinking

Before introducing today's protagonist, let's understand the idea of asynchrony, or let's start with a diagram

The asynchronous idea is: when you are ready, tell me. I'll do other things first

As shown in the corresponding figure, in the process of making eggs, I won't wait here because it takes a long time. I'll grab some cakes first (complete other operations that don't take that long)

Today's pig's feet, the Future model in jdk

Because the Future pattern (the core idea is asynchronous call) is very common, the JDK has prepared the implementation for us

In short, through Future, you can define a task and let it execute. At some time in the Future, you can obtain data through the API. If you can't obtain it, it will be blocked all the time

```//There are five methods in the Future interface. Would you like to know more? Just read the interface documentation directly
public interface Future<V> {

boolean cancel(boolean mayInterruptIfRunning);

boolean isCancelled();

boolean isDone();

V get() throws InterruptedException, ExecutionException;

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

```

This is an interface, and what we really use is its subclass FutureTask

Let's look at the FutureTask class

It can be found that his construction method needs to pass in a class that implements Callable or Runnable. In that case, let's create another BuyTask

```/**
* @Author: Amg
* @Date: Created in 21:15 2021/10/24
* @Description: TODO
*/

}

@Override
public String call() throws Exception {
}
}

```

```public class MyFutureTask {

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

final long start = System.currentTimeMillis();

System.out.println("I bought it all");
System.out.println("Total time:" + (System.currentTimeMillis() - start) / 1000);

if (!executorService.isShutdown()) executorService.shutdown();
}
}

//output
Food is being prepared:[egg puffs],Company:[5],Waiting time:[SECONDS]
Food is being prepared:[shredded pancake],Company:[10],Waiting time:[SECONDS]
BuySomethingToEat[foodName='egg puffs', unit=SECONDS, waitSecond=5] is done!
BuySomethingToEat[foodName='shredded pancake', unit=SECONDS, waitSecond=10] is done!
I bought it all
Total time: 16

//Or
Food is being prepared:[shredded pancake],Company:[10],Waiting time:[SECONDS]
Food is being prepared:[egg puffs],Company:[5],Waiting time:[SECONDS]
BuySomethingToEat[foodName='egg puffs', unit=SECONDS, waitSecond=5] is done!
BuySomethingToEat[foodName='shredded pancake', unit=SECONDS, waitSecond=10] is done!
I bought it all
Total time: 16
```

summary

The Future model has a wide range of uses

• Common are SQL asynchronous calls. When a SQL takes a little longer, you can first execute other steps that are not related to the SQL process to save time;
• There are also computationally intensive operations
• There are also asynchronous calls to other system interfaces

There are more advanced uses for Future. At present, I just briefly introduce how Future and its implementation class FutureTask are used, which is enough for understanding the idea of Future and simple use

However, there will be more advanced usage of Future, such as the enhancement of Future in guava, which will be further introduced later

Topics: Java