Java Advanced Application - Multithreading - (4) Introduction and Use of FutureTask

Introduction and use of Java multi-threaded FutureTask

FutureTask belongs to the java.util.concurrent package; FutureTask represents a cancellable asynchronous computation. The FutureTask class provides a basic implementation of a Future, with methods for starting and canceling computations, querying whether computations are complete, and retrieving computation results. The result can only be retrieved after the computation has completed; the get method will block if the computation has not completed. Once the calculation is complete, it cannot be restarted or canceled (unless the calculation is called with runAndReset())

insert image description here
As can be seen from the above FutureTask class diagram, FutureTask implements the RunnableFuture interface, and the RunnableFuture interface inherits the Runnable interface and Future interface, so FutureTask has both Runnable and Future features

insert image description here

1. Construction method

public FutureTask(Callable callable) Creates a FutureTask that will execute the given Callable at runtime. Parameters: callable means a callable task.
public FutureTask(Runnable runnable,V result) Creates a FutureTask that will execute the given Runnable at runtime and arranges for a get that will return the given result upon successful completion. Parameters: runnable indicates the runnable task; result indicates the result returned after successful completion.
2. Commonly used methods

public boolean isCancelled() Returns true if this task was canceled before completing normally.
public boolean isDone() returns true if the task is done.
public V get() Waits for the computation to complete, then retrieves its result.
public V get(long timeout, TimeUnit unit) waits at most the given time for computation to complete if necessary, and then retrieves its result (if available).
public boolean cancel(boolean mayInterruptIfRunning) attempts to cancel execution of this task.
protected void set(V v) sets the result of this future to the given value, unless this future has already been set or has been cancelled.

Case
Multi-tasking computing is performed through an example, and the execution result can be obtained asynchronously through the get() method.

1. Create a computing task class, implement the Callable interface, and rewrite the call method

package com.hz.thread.FutureTask;

import java.util.concurrent.Callable;

// 创建一个计算任务类,实现Callable接口,重写call方法
 
public class ComputeTask implements Callable<Integer> {
    
    

    private String taskName;//任务名称

    //任务构造器
    public ComputeTask(String taskName) {
    
    
        this.taskName = taskName;
        System.out.println("创建【计算任务】开始,计算任务名称:" + taskName);
    }

    //计算任务的方法
    @Override
    public Integer call() throws Exception {
    
    
        Integer result = 0;
        for (int i = 1; i <=50; i++) {
    
    
            result = +i;
        }
        System.out.println("【计算任务】"+taskName +"执行完成。");
        return result;
    }
}

2. Create a test class

package com.hz.thread.FutureTask;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class Demo {
    
    
    public static void main(String[] args) {
    
    
        //任务集合
        List<FutureTask<Integer>> futureTasks  = new ArrayList<>();
        //创建固定长度的线程池
        ExecutorService pool = Executors.newFixedThreadPool(5);
        for (int i = 1; i <= 10; i++) {
    
    
            //实例化FutureTask,传入计算任务类
            FutureTask<Integer> futureTask = new FutureTask<>(new ComputeTask(i + ""));
            //添加到任务集合中
            futureTasks.add(futureTask);
            //提交任务到线程池
            pool.submit(futureTask);
        }
        System.out.println("所有【计算任务】提交完毕,主线程开始执行");

        System.out.println("【主线程任务】开始============");
        //主线程睡眠5秒,模拟主线程做某些任务
        try {
    
    
            Thread.sleep(5000);
            System.out.println("【主线程任务】开始执行某些任务============");
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("【主线程任务】结束============");

        //用于打印任务执行结果
        Integer result = 0;
        for (FutureTask<Integer> task : futureTasks) {
    
    
            try {
    
    
                //FutureTask的get()方法会自动阻塞,知道得到任务执行结果为止
                result += task.get();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            } catch (ExecutionException e) {
    
    
                e.printStackTrace();
            }
        }
        //关闭线程池
        pool.shutdown();
        System.out.println("多线程多任务执行结果:" + result);

    }

}

3. The output results are as follows:

Create [calculation task] start, calculation task name: 1
create [calculation task] start, calculation task name: 2
create [calculation task] start, calculation task name: 3
create [calculation task] start, calculation task name: 4
create [ Computing task] start, computing task name: 5
Create [computing task] start, computing task name: 6
create [computing task] start, computing task name: 7
create [computing task] start, computing task name: 8
create [computing task ] Start, calculation task name: 9
create [calculation task] start, calculation task name: 10
all [computation tasks] are submitted, the main thread starts to execute
[main thread task] start ============
[Calculation task] 1 is completed.
[Calculation task] 2 is completed.
[Calculation task] 6 execution completed.
[Calculation task] 7 is completed.
[Calculation task] 9 is completed.
[Calculation task] 10 execution completed.
[Calculation task] 8 is completed.
[Calculation task] 4 is completed.
[Calculation task] 3 is completed.
[Calculation task] 5 is completed.
[Main thread task] Start to execute some tasks ============
[Main thread task] End =============
Multi-thread multi-task execution result: 500

4 Conclusion
insert image description here

The get() method of the FutureTask class can be used to obtain the execution result asynchronously. No matter how many times the FutureTask calls the run() or call() method, it can ensure that the Runable or Callable task is executed only once.

Guess you like

Origin blog.csdn.net/weixin_45817985/article/details/130950522