50-What are the points to note when using Future? Does Future spawn new threads?

Points to note for Future
  1. It is easy to block when the for loop obtains the results of the Future in batches, and the timeout limit should be used when the get method is called.

For Futures, the first point of note is that it is easy to block when the for loop obtains the results of Futures in batches. When calling the get method, timeout should be used to limit.

Let's take a look at what this situation is.

First, suppose there are a total of four tasks to be executed, we put them in the thread pool, and then it is obtained in the order from 1 to 4, which is to execute the get() method to obtain, the code is as follows :

public class FutureDemo {
    
    
    public static void main(String[] args) {
    
    
        //创建线程池
        ExecutorService service = Executors.newFixedThreadPool(10);
        //提交任务,并用 Future 接收返回结果
        ArrayList<Future> allFutures = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
    
    
            Future<String> future;
            if (i == 0 || i == 1) {
    
    
                future = service.submit(new SlowTask());
            } else {
    
    
                future = service.submit(new FastTask());
            }
            allFutures.add(future);
        }
        for (int i = 0; i < 4; i++) {
    
    
            Future<String> future = allFutures.get(i);
            try {
    
    
                String result = future.get();
                System.out.println(result);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            } catch (ExecutionException e) {
    
    
                e.printStackTrace();
            }
        }
        service.shutdown();
    }
    static class SlowTask implements Callable<String> {
    
    
        @Override
        public String call() throws Exception {
    
    
            Thread.sleep(5000);
            return "速度慢的任务";
        }
    }
    static class FastTask implements Callable<String> {
    
    
        @Override
        public String call() throws Exception {
    
    
            return "速度快的任务";
        }
    }
}

It can be seen that in the code we created a new thread pool and used a list to store 4 Futures. Among them, the tasks corresponding to the first two Futures are slow tasks, that is, the SlowTask below the code, and the tasks corresponding to the last two Futures are fast tasks. Slow tasks take 5 seconds to complete when they are executed, while fast tasks can be executed very quickly, and it takes almost no time.

After submitting these 4 tasks, we use a for loop to execute the get method on them in turn to obtain their execution results, and then print the results.

The execution results are as follows:

速度慢的任务
速度慢的任务
速度快的任务
速度快的任务

As you can see, the result of this execution is to print 4 lines of statements, the first two are slow tasks, and the latter two are fast tasks. Although the result is correct, it actually waits for 5 seconds during execution, and then prints out these 4 lines of statements very quickly.
Insert picture description here
There is a problem here, that is, the amount of the third task is relatively small, it can quickly return the result, and the fourth task will also return the result immediately. But because the first two tasks are very slow, we will get stuck on the first task when we use the get method to execute. That is to say, although the results of the third and fourth tasks are obtained very early at this time, we still cannot obtain the third and fourth tasks in time when we use this for loop method to obtain the results. The result of the task. We won’t be able to get the result of the first task until 5 seconds later, and then we can get the result of the second task, and then it’s the turn of the third and fourth tasks.

Assuming that due to network reasons, the first task may not be able to return results for up to 1 minute, then at this time, our main thread will remain stuck, which affects the efficiency of the program.

At this point, we can use Future's get(long timeout, TimeUnit unit) method with timeout parameters to solve this problem. The function of this method is that if the result is not returned within a limited time, a TimeoutException will be thrown, and then the exception can be caught, or thrown up again, so that it will not always Stuck.

2. Future's life cycle cannot be regressed

The life cycle of a Future cannot be regressed. Once the task is completed, it will permanently stop in the "completed" state, and cannot restart from the beginning, nor can a Future that has completed its calculations re-execute the task again.

This is the same as the state of threads and thread pools, and the states of threads and thread pools cannot be regressed. Regarding the thread status and flow path, it has been mentioned in 3 before, as shown in the figure.
Insert picture description here
For those who have forgotten, turn back and take another look!

Does Future spawn new threads?

Finally, let's answer this question again: Does Future spawn new threads?

There is a saying that in addition to inheriting the Thread class and implementing the Runnable interface, there is a third way to generate a new thread, that is, using Callable and Future, which is called the way to create a thread with a return value. This statement is incorrect.

In fact, Callable and Future can't generate new threads by themselves, they need to use other such as Thread class or thread pool to perform tasks. For example, after the Callable is submitted to the thread pool, it is actually the threads in the thread pool that actually execute the Callable, and the threads in the thread pool are generated by the ThreadFactory. The new threads generated here have nothing to do with Callable and Future, so Future No new threads are generated.

Two points to note about Future: First, the timeout limit should be used when getting; Second, the life cycle of Future cannot be regressed; Then it is said that Callable and Future are not actually the third way to create a new thread.

Guess you like

Origin blog.csdn.net/Rinvay_Cui/article/details/111056577