📜  Java中的Future和FutureTask

📅  最后修改于: 2022-05-13 01:55:06.767000             🧑  作者: Mango

Java中的Future和FutureTask

先决条件:未来和可调用

未来:

Future接口提供了检查计算是否完成、等待其完成和检索计算结果的方法。计算完成后,使用 Future 的 get() 方法检索结果,并阻塞直到完成。
Future 和 FutureTask 都在Java 1.5 的Java .util.concurrent 包中可用。

未来任务:

  1. FutureTask 实现Future 接口和RunnableFuture 接口,意思是可以将FutureTask 用作Runnable 并提交给ExecutorService 执行。
  2. 当调用 Future.submit() Callable 或 Runnable 对象时,大部分时间 ExecutorService 创建 FutureTask,也可以手动创建它。
  3. FutureTask 就像一个闩锁。
  4. FutureTask 表示的计算是用 Callable 接口实现的。
  5. 它实现了 Future 或 Callable 接口。
  6. get() 方法的行为取决于任务的状态。如果任务没有完成,get() 方法会等待或阻塞,直到任务完成。任务完成后,它会返回结果或抛出 ExecutionException。

使用 Future 的一个例子是使用线程池。当向 ExecutorService 提交一个运行时间较长的任务时,它会立即返回一个 Future 对象。此 Future 对象可用于完成任务并获取计算结果。

示例:创建两个任务。一个任务完全执行后,等待2000毫秒后,第二个任务正在执行

注意:在线 IDE 在 sleep() 方法上无法正常工作。

Java
// Java program do two FutureTask
// using Runnable Interface
 
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;
 
class MyRunnable implements Runnable {
 
    private final long waitTime;
 
    public MyRunnable(int timeInMillis)
    {
        this.waitTime = timeInMillis;
    }
 
    @Override
    public void run()
    {
        try {
            // sleep for user given millisecond
            // before checking again
            Thread.sleep(waitTime);
 
            // return current thread name
            System.out.println(Thread
                                   .currentThread()
                                   .getName());
        }
 
        catch (InterruptedException ex) {
            Logger
                .getLogger(MyRunnable.class.getName())
                .log(Level.SEVERE, null, ex);
        }
    }
}
 
// Class FutureTaskExample execute two future task
class FutureTaskExample {
 
    public static void main(String[] args)
    {
        // create two object of MyRunnable class
        // for FutureTask and sleep 1000, 2000
        // millisecond before checking again
        MyRunnable myrunnableobject1 = new MyRunnable(1000);
        MyRunnable myrunnableobject2 = new MyRunnable(2000);
 
        FutureTask
            futureTask1 = new FutureTask<>(myrunnableobject1,
                                           "FutureTask1 is complete");
        FutureTask
            futureTask2 = new FutureTask<>(myrunnableobject2,
                                           "FutureTask2 is complete");
 
        // create thread pool of 2 size for ExecutorService
        ExecutorService executor = Executors.newFixedThreadPool(2);
 
        // submit futureTask1 to ExecutorService
        executor.submit(futureTask1);
 
        // submit futureTask2 to ExecutorService
        executor.submit(futureTask2);
 
        while (true) {
            try {
 
                // if both future task complete
                if (futureTask1.isDone() && futureTask2.isDone()) {
 
                    System.out.println("Both FutureTask Complete");
 
                    // shut down executor service
                    executor.shutdown();
                    return;
                }
 
                if (!futureTask1.isDone()) {
 
                    // wait indefinitely for future
                    // task to complete
                    System.out.println("FutureTask1 output = "
                                       + futureTask1.get());
                }
 
                System.out.println("Waiting for FutureTask2 to complete");
 
                // Wait if necessary for the computation to complete,
                // and then retrieves its result
                String s = futureTask2.get(250, TimeUnit.MILLISECONDS);
 
                if (s != null) {
                    System.out.println("FutureTask2 output=" + s);
                }
            }
 
            catch (Exception e) {
                Sysmtem.out.println("Exception: " + e);
            }
        }
    }
}


输出:

FutureTask1 output=FutureTask1 is complete
Waiting for FutureTask2 to complete
Waiting for FutureTask2 to complete
Waiting for FutureTask2 to complete
Waiting for FutureTask2 to complete
FutureTask2 output=FutureTask2 is complete
Both FutureTask Complete

参考

  • https://docs.oracle.com/javase/7/docs/api/java Java
  • https://docs.oracle.com/javase/7/docs/api/java Java