今天看书,有关于 FutureTask 的介绍,感觉还蛮有意思的,可以用它来做一些比较花时间的事情。下面打个通俗的比方来说明一下它的用处:
比如,早上一大早的去公交站台等公交,但那该死的公交20分钟才一班。如果一直死等公交,那么这20分钟无疑就被浪费了。我们可以利用这20分钟,去买个韭菜饼,再买一盒豆浆,然后一边吃一边等。这样就明显提高了时间的利用率。
下面给出一个段简单的代码来说明一下它的使用:
public class Preloader { private final FutureTask<Long> future = new FutureTask<Long>(new Callable<Long>() { @Override public Long call() throws Exception { Thread.currentThread().setName("Thread(3)"); System.out.println(Thread.currentThread().getName() + ": simulate a latency "); try { Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ": the latency is over"); return Math.round(Math.random() * 1000); } }); private final Thread loader = new Thread(future); public void start() { System.out.println(Thread.currentThread().getName() + ": start the loader"); loader.start(); System.out.println(Thread.currentThread().getName() + ": loader started"); } public Long get() { try { System.out.println(Thread.currentThread().getName() + ": begin to get"); long start = System.currentTimeMillis(); Long result = future.get(); System.out.println(Thread.currentThread().getName() + ": got result: " + result); System.out.println(Thread.currentThread().getName() + ": spent time: " + (System.currentTimeMillis() - start)); return result; } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ": got nothing"); return null; } public static void main(String[] args) { Thread.currentThread().setName("Thread(main)"); final Preloader pl = new Preloader(); pl.start(); // try to get the result before the latency is over new Thread(new Runnable() { @Override public void run() { Thread.currentThread().setName("Thread(1)"); pl.get(); } }).start(); // try to get the result after the latency is over new Thread(new Runnable() { @Override public void run() { Thread.currentThread().setName("Thread(2)"); try { Thread.sleep(6000); pl.get(); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }
以上代码的运行结果为:
main: start the loader main: loader started Thread(3): simulate a latency Thread(1): begin to get Thread(3): the latency is over Thread(1): got result: 917 Thread(1): spent time: 5006 Thread(2): begin to get Thread(2): got result: 917 Thread(2): spent time: 0
通过上面运行的结果,我们可以得到以下结论:
① 在FutureTask执行完了之前(即call执行完了之前),去进行get的话,将被会一直阻塞至FutureTask执行完了才会返回。
② FutureTask执行完了之后,再调用get的话,会立刻返回相应的结果
③ FutureTask只会执行一次,所以,多次调用get方法,返回的值始终是一样的。
相关推荐
下面是一个使用FutureTask实现多任务计算的示例代码: ```java public class FutureTaskForMultiCompute { public static void main(String[] args) { FutureTaskForMultiCompute inst = new ...
Java FutureTask类使用案例解析 Java FutureTask类是一种异步计算的工具,用于执行长时间的任务并获取结果。它实现了Runnable和Future接口,既可以作为一个Runnable对象提交给Executor执行,也可以作为一个Future...
在本篇文章中,我们将深入探讨`ThreadPoolTaskExecutor`的配置及其使用,并结合`FutureTask`来讨论异步任务处理。 首先,让我们了解`ThreadPoolTaskExecutor`的基本配置。在Spring中,我们通常通过在配置文件或Java...
- `FutureTask`内部使用了一个`volatile`变量`state`来管理任务的状态,确保多线程环境下的可见性和有序性。 - 当`FutureTask`被提交给`Executor`时,`Executor`实际上是在另一个线程中调用`run()`方法。 - 如果...
在示例代码中,我们首先使用Lambda表达式创建了一个Callable对象,然后将该实例包装成了一个FutureTask对象。主线程中当循环变量i等于20时,程序启动以FutureTask对象为target的线程。程序最后调用FutureTask对象的...
在提供的代码示例中,创建了一个ExecutorService,并提交了一个FutureTask。任务是一个模拟1秒CPU空转的Callable。当调用`future.get()`时,主线程会被阻塞,直到任务完成。如果使用`get(long timeout, TimeUnit ...
下面是一个使用`Callable`和`FutureTask`的简单示例: ```java import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import ...
在Android开发中,多线程是必不可少的一部分,特别是在执行耗时操作如网络请求、数据库操作等时,为了不...在给定的`AndroidFutureCallableDemo`示例中,可能就是展示了如何使用这些工具来处理Android中的多线程任务。
在Java并发编程中,通常我们会使用`ExecutorService`来提交任务,而`Future`和`FutureTask`就是与这些任务交互的关键。 首先,`Future`是一个接口,它提供了一种机制来检查异步计算是否完成,以及在计算完成后获取...
本示例代码旨在帮助开发者深入理解并掌握在Android环境中如何有效地使用多线程。以下将详细介绍这5种不同的线程实现方式及其应用场景。 1. **Thread类**: Android系统基于Java,因此我们可以直接使用Java的`...
在阅读《FutureTaskTest》这个压缩包中的文件时,你可能会看到如何使用`FutureTask`来创建、执行、管理和获取多线程任务的示例代码。通过对这些示例的理解和实践,你可以更好地掌握如何在Java中实现高效的多线程并发...
从上面的代码可以看出,Callable 接口的使用非常简单。在多线程环境中,Callable 接口可以返回结果,使得多线程编程更加方便。 Callable 接口是一个非常有用的工具,在多线程编程中可以发挥重要作用。希望本文对...
本篇文章将深入探讨Java中的并发同步器,并通过具体的例子来解释如何使用`FutureTask`来实现线程之间的协作。 #### 2. FutureTask简介 `FutureTask`是Java并发编程中非常重要的一个类,它是`Future`接口的一个具体...
在Java多线程编程中,CyclicBarrier、Callable、Future和FutureTask是四个重要的组件,它们各自提供了不同的功能,帮助开发者更好地管理和协调并发任务。接下来,我们将深入探讨这些组件的特性和使用方法。 首先,...
本文将详细解释Callable接口的使用、适配器模式在创建线程中的应用,以及FutureTask在其中的角色。 首先,Callable接口与Runnable接口类似,都是用于创建新线程的接口。但是,Runnable接口的run()方法无返回值,而...
通过上述分析,我们可以看出,在Java中,使用`Callable`接口和`Future`或`FutureTask`可以轻松地实现异步执行任务并获取结果。这种方法非常适合那些需要等待长时间运行的任务完成并获取结果的场景。同时,通过使用...
`TestBlockingQueue.java`可能包含如何使用`ArrayBlockingQueue`、`LinkedBlockingQueue`等实现线程间的通信和数据交换的示例。 3. **CompletionService**:`CompletionService`提供了一种获取异步任务结果的机制,...
Java构建高效结果缓存方法示例 Java构建高效结果缓存方法示例主要...Java构建高效结果缓存方法示例通过使用HashMap和ConcurrentHashMap两种方式来实现缓存,解决了线程安全问题,并且使用FutureTask来实现缓存重用。
我们创建一个实现了Callable的类,然后使用`FutureTask`包装它,最后通过Thread启动。示例代码: ```java class MyCallable implements Callable<String> { public String call() throws Exception { // 线程...
3.4.2 示例:使用Volatile类型来发布不可变对象 3.5 安全发布 3.5.1 不正确的发布:正确的对象被破坏 3.5.2 不可变对象与初始化安全性 3.5.3 安全发布的常用模式 3.5.4 事实不可变对象 3.5.5 可变对象 3.5.6 ...