1. import java.util.Random;
  2. import java.util.concurrent.Callable;
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Executors;
  5. import java.util.concurrent.Future;
  6. /**
  7. * 关于Callable和Future的简单使用:有返回值的线程
  8. *
  9. */
  10. public class CallableAndFutureTest {
  11. public static void main(String[] args) {
  12. // 创建5个固定线程的数量的线程池
  13. ExecutorService threadPool = Executors.newFixedThreadPool( 5 );
  14. // 提交20个任务对象
  15. for ( int i = 0 ; i < 20 ; i++){
  16. Future<String> future = threadPool.submit( new Callable<String>() {
  17. @Override
  18. public String call() throws Exception {
  19. return new Random().nextInt() + "" ;
  20. }
  21. });
  22. try {
  23. sop(i+ ": " + future.get()); // 获取结果并打印
  24. } catch (Exception e) {
  25. // future有可能为null,为了防止空指针异常,有必要做出判断
  26. if ( future != null ){
  27. // 抛出异常用,取消任务,并关闭线程池
  28. future.cancel( true );
  29. threadPool.shutdownNow(); // 可选
  30. }
  31. throw new RuntimeException(e);
  32. }
  33. }
  34. }
  35. private static void sop(Object obj){
  36. System.out.println(obj);
  37. }
  38. }
  39. /**
  40. * Future:
  41. *      Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获
  42. *      取计算的结果。计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此
  43. *      方法。取消则由 cancel 方法来执行。还提供了其他方法,以确定任务是正常完成还是被取消
  44. *      了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的
  45. *      结果,则可以声明 Future<?> 形式类型、并返回 null 作为底层任务的结果。
  46. *
  47. * Future的体系:
  48. *          Future<V>
  49. *              |--- RunnableFuture<V>
  50. *              |--- ScheduledFuture<V>
  51. *                  |--- RunnableScheduledFuture<V>
  52. *
  53. *      1)RunnableFuture:
  54. *          public interface RunnableFuture<V> extends Runnable, Future<V>
  55. *          实现了 Runnable 的 Future,成功执行 run 方法可以完成 Future 并允许访问其结果。
  56. *
  57. *      2)RunnableScheduledFuture:
  58. *          public interface RunnableScheduledFuture<V>extends RunnableFuture<V>, ScheduledFuture<V>
  59. *
  60. *      3)对于Future体系,一般只需要Future就可以满足到需求
  61. *
  62. * Future中的方法:
  63. *      V get():
  64. *          等待任务执行完毕,获取结果,阻塞性的方法;
  65. *
  66. *      boolean cancel(boolean mayInterruptIfRunning):
  67. *          试图取消对此任务的执行。如果任务已完成、或已取消,或者由于某些其他原因而无法取消,则此尝试将失败。当调用 cancel
  68. *          时,如果调用成功,而此任务尚未启动,则此任务将永不运行。如果任务已经启动,则 mayInterruptIfRunning 参数确定是
  69. *          否应该以试图停止任务的方式来中断执行此任务的线程。
  70. *          此方法返回后,对 isDone() 的后续调用将始终返回 true。如果此方法返回 true,则对 isCancelled()的后续调用将始终返
  71. *          回 true。
  72. *
  73. *      boolean isCancelled():
  74. *
  75. *      boolean isDone():
  76. *
  77. *      V get(long timeout,TimeUnit unit):
  78. *
  79. *      详细情况请查阅API
  80. *
  81. */
分类: java_线程2012-07-03 19:25 53人阅读 评论(0) 收藏 举报[java] view plaincopyimport java.util.Random;  import java.util.concurrent.Callable;  import java.util.concurrent.ExecutorServi
callable 线 future .get()方法能获取到当前 线 程的执行结果,但是会阻塞当前 线 程,即当前 线 程执行结束获取到结果后才会继续执行下一个 线 程,解决方法: 创建一个List数组存储funture,在所有 线 程执行以后遍历list获取结果。 int count = 0; List< Future <Integer>> res = new ArrayList<>(); ExecutorService executorService = Executors.newCached
Completable Future 优化接口性能案例需求背景解决方案 在教育中心所有课程详情页都大致包含下面这么些,每种卡片的数据可能来自不同的数据源。数据源可能就是缓存数据,也可能是第三方的接口 返回 数据。因此对于这个接口一次性 返回 这么多卡片信息还是有点重的,我们尽量要使得每个卡片请求的数据要够快。对于头部影藏卡片而言,在数据适配阶段串行调用了三个第三方接口,而且每个接口最大超时时间outTime=200~300ms,对整个接口的性能还是有很大影响。 课程详情头部隐藏卡片,课程详情头部促销卡片,
2019-08-07 工作中遇到的问题 大概是: 有个 线 程池满了,然后新的任务 使用 Completable Future .supplyAsync执行,用 future 1.get(1, TimeUnit.SECONDS)) 去获取的时候报错 java .util.concurrent.TimeoutException 报错 java .util.concurrent.TimeoutException觉得很奇怪;随...
线 程池 使用 Future Task的时候如果拒绝策略设置为了 DiscardPolicy和DiscardOldestPolicy并且在被拒绝的任务的 Future 对象上调用无参get方法那么调用 线 程会一直被阻塞。 下面就通过一个 简单 的例子来复现问题: public class Future Test { 在jdk5中,我们通过 使用 Future Callable ,可以在任务执行完毕后得到任务执行结果。可以 使用 isDone检测计算是否完成, 使用 cancle停止执行任务, 使用 阻塞方法get阻塞住调用 线 程来获取 返回 结果, 使用 阻塞方式获取执行结果,有违异步编程的初衷,而且 Future 的异常只能自己内部处理。 jdk8中加入了实现类Completable Future <T>,用于异步编程。底层做任务 使用 的是ForkJoin, 顾名思义,是将任务的数据集分为多个子数据集,而每个子集,都可以由独立的子任
记录问题,暂时还没得到解决 最近在工作中遇到这个问题,自己找了很多资料,始终没得到解决,所以发出来看看是否有人跟我遇到同样的问题,一起讨论 关于这个 Future 接口有以下几个方法 public interface Future <V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedE
Java 应用中,绝大多数情况下都是通过同步的方式来实现交互处理的;但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是 使用 线 程来完成此类任务,其实,在spring3.x之后,就已经内置了@Async来完美解决这个问题。 1.@Async介绍 在Spring中,基于@Async标注的方法,称之为异步方法;这些方法将在执行的时候,将会在独立的 线 程中被执行,调用者无...
thread = (Scheduled Future &lt;BaseThread&gt;) future .get(10, TimeUnit.SECONDS); 因业务需要,需要做定时任务。 在打印日志的时候试图调用其 返回 future 的get方法获取对应的执行 线 程。然后总是卡在那一行代码。经过调试,该方法应该只能在任务运行时runtime阶段才能访问到对应的执行 线 程,非执行阶段无法获取。以此做... * @throws CancellationException {@inheritDoc} public V get() throws InterruptedException, ExecutionException { int s = state;
提到这个 Future ,相信英文好的人都知道,这个单词的意思是表示未来,今天的用法也跟这个单词的意思相类似 在做开发中我们经常遇到这样一个问题,就是一个问题需要执行比较久,但是有需要等待它的结果,于是我们会 使用 线 程来做,但是 使用 线 程也会到一个问题,我什么时候调用呢,如果调用早了肯定会出现空指针异常的,今天我的就 使用 这个 future 来解决这个问题。 Future 相当于拿到一个应用,这个引用在 线 程没有执...
### 回答1: 可以 使用 Python 的 concurrent. future s 库中的 ThreadPoolExecutor 类来 使用 callable future 创建 线 程。首先,需要创建一个 ThreadPoolExecutor 实例,然后 使用 submit() 方法将 callable 包装在一个 future 对象中并提交给 线 程池执行。例如: from concurrent. future s import ThreadPoolExecutor def my_function(): # do something executor = ThreadPoolExecutor() future = executor.submit(my_function) # do other things result = future .result() # block until the function is complete and return the result 在这种情况下, `my_function` 将在另一个 线 程中运行,并且可以 使用 ` future .result()` 来阻塞等待结果并获取 返回 。 ### 回答2: 使用 callable future 创建 线 程的主要目的是为了充分利用多核 CPU 的能力,加速程序的执行速度。 Callable 是一个接口,通常用于表示一个可调用的对象,即一个函数或者一个方法。通过实现 Callable 接口,并重写 call() 方法来创建一个可调用对象。 Future 是一个接口,用于表示一个异步计算的结果,它有三种状态:正在进行、已经完成、已经取消。 Callable Future 结合 使用 ,可以实现异步执行一个任务的功能,即先向 线 程池提交一个 Callable 对象, 线 程池会为该对象分配一个执行 线 程,并 返回 一个 Future 对象。通过调用 Future 对象的 get() 方法,可以等待该计算完成,从而获取 返回 使用 Callable Future 创建 线 程的步骤如下: 1. 创建一个 Callable 对象,并实现 call() 方法,该方法 返回 一个 。 2. 创建一个 ExecutorService 对象,该对象维护着一个 线 程池。 3. 向 线 程池提交 Callable 对象,该方法会 返回 一个 Future 对象。 4. 通过调用 Future 对象的 get() 方法,可以等待 Callable 对象执行完毕,并获取 返回 。 例如,下面的代码创建了一个 Callable 对象,并通过 ExecutorService 对象将其提交到 线 程池中执行,然后通过 Future 对象获取执行的结果: import java .util.concurrent.*; public class Callable Demo { public static void main(String[] args) throws Exception { // 创建一个 Callable 对象 Callable <String> task = () -> { System.out.println("Task is running..."); Thread.sleep(5000); // 模拟一个耗时的操作 return "Hello, World!"; // 创建一个 ExecutorService 对象 ExecutorService executor = Executors.newFixedThreadPool(1); // 向 线 程池提交 Callable 对象,并 返回 一个 Future 对象 Future <String> future = executor.submit(task); // 等待任务执行完毕,并获取执行的结果 String result = future .get(); System.out.println(result); // 关闭 线 程池 executor.shutdown(); 上述代码创建了一个 Callable 对象 task,该对象模拟了一个耗时的操作,然后创建了一个 ExecutorService 对象 executor,该对象维护着一个固定大小为 1 的 线 程池。接着,向 线 程池提交 Callable 对象 task,并 返回 一个 Future 对象 future 。最后,通过调用 Future 对象的 get() 方法等待 Callable 对象 task 执行完毕,并获取执行的结果 result。最后,关闭 线 程池 executor。 ### 回答3: 使用 callable future 创建 线 程,可以让我们更加灵活地管理 线 程池和多 线 程任务。相比于直接 使用 Thread类创建 线 程, 使用 callable 可以让我们定义更加灵活的任务, callable 既可以 返回 结果,也可以抛出异常。而 使用 Future 则可以让我们更好地掌控 线 程的执行状态,比如可以查询某个任务是否已经完成,可以等待某个任务的完成。下面,我将进一步介绍 callable future 的用法。 首先,我们需要了解什么是 callable callable 是一个接口,其中包含一个call()方法,call()方法包含了要执行的任务。我们可以 使用 callable 创建一个实现了该接口的类的实例,从而将任务封装起来,以便于将该任务提交给 线 程池执行。创建 callable 的基本语法如下: class My Callable implements Callable <Integer> { public Integer call() throws Exception { // 在这里编写任务代码 Callable <Integer> callable = new My Callable (); 上面的代码中,我们创建了一个实现了 Callable 接口的类My Callable ,该类包含了任务代码,可以 返回 一个Integer类型的结果。然后,我们创建了一个 callable 对象,该对象将用于将任务提交给 线 程池。 接下来,我们需要介绍 future future 实现了 Future 接口,表示一个异步的计算结果。当我们将一个任务提交给 线 程池执行时,会 返回 一个 Future 对象,我们可以通过该对象来监控任务的执行状态,等待任务的完成,并获取任务的结果。创建 Future 对象的基本语法如下: ExecutorService executor = Executors.newFixedThreadPool(1); Future <Integer> future = executor.submit( callable ); 上面的代码中,我们创建了一个 线 程池executor,将 callable 对象提交给 线 程池,并 返回 了一个 future 对象,该对象表示了可调用对象的计算结果。 最后,我们需要了解如何 使用 Future 对象监控任务的执行状态和获取结果。 Future 对象提供了一些方法,可以用于查询任务的执行状态和获取任务的结果。常用的方法包括: 1. isDone():查询任务是否已经完成; 2. get():等待任务完成,并获取任务的结果,如果任务抛出异常,则该方法将会重新抛出该异常。 完整代码如下: import java .util.concurrent. Callable ; import java .util.concurrent.ExecutorService; import java .util.concurrent.Executors; import java .util.concurrent. Future ; public class Callable Future Demo { public static void main(String[] args) throws Exception { // 创建可调用对象 Callable <Integer> callable = new My Callable (); // 创建 线 程池 ExecutorService executor = Executors.newFixedThreadPool(1); // 提交任务并获取 Future 对象 Future <Integer> future = executor.submit( callable ); // 查询任务状态 while (! future .isDone()) { System.out.println("任务未完成,等待1秒..."); Thread.sleep(1000); // 获取任务结果 Integer result = future .get(); System.out.println("任务结果:" + result); // 关闭 线 程池 executor.shutdown(); class My Callable implements Callable <Integer> { public Integer call() throws Exception { System.out.println(Thread.currentThread().getName() + "开始执行任务..."); Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "完成任务."); return 100; 上面的代码中,我们创建了一个可调用对象My Callable ,并且将该对象提交给了一个 线 程池executor。然后,我们 使用 了一个while循环,来等待任务完成。一旦任务完成,我们 使用 future .get()方法获取了任务的结果,并打印了结果。最后,我们调用了executor.shutdown()方法关闭了 线 程池。 使用 callable future 创建 线 程,可以让我们更加灵活地管理 线 程池和多 线 程任务,可以有效提高程序的并发效率和性能。如果需要 使用 线 程实现异步的任务执行,可以考虑 使用 callable future