本文可作为传智播客《张孝祥-Java多线程与并发库高级应用》的学习笔记。

在前面写的代码中,所有的任务执行也就执行了,run方法的返回值为空。

这一节我们说的Callable就是一个可以带返回值的线程模型。而它的返回值由Future接着。

先看看Callable

java.util.concurrent Interface Callable<V>

接口里面只有一个call方法,参数为空,返回值为T。



首先我们看看javadoc里面 Thread()的构造函数的参数没有Callable类型的,换言之,不能通过Thread().start的方式类运行Callable。



那么如何使用Callable呢?

有一个类叫

public class FutureTask<V> extends Object implements RunnableFuture<V>

其中RunnableFuture实现了Runnable接口。

而Runnable的构造函数的参数却可以使Callable。

说了这么多,我们看看代码:

使用FutureTask

public static void main(String[] args) {
        Callable<Integer> callable = new Callable<Integer>() {
            public Integer call() throws Exception {
                int a=new Random().nextInt(100);
                System.out.println(a+"   ss");
                return a;
            }
        };  

        FutureTask<Integer> ft=new FutureTask<Integer>(callable);
//        for (int i = 0; i < 5; i++)
//            new Thread(ft).start();

    //    new Thread(ft).start();
        ft.run();
        try {
            System.out.println("得到结果 "+ft.get());
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

运行结果

69   ss

得到结果 69

没有什么问题。

不过大家估计对代码中让new Thread(ft).start()运行5次的部分比较奇怪。

打开注释后,输出的结果还是两行,call方法只运行了一次。为什么?不知道。

我们再看看Future类

带参数的get,就是给个时间限制,如果再n个单位时间内,还没有获得结果,就抛出异常。

使用线程池

public static void main(String[] args) {
    ExecutorService threadPool =  Executors.newSingleThreadExecutor();
    Future<String> future =
        threadPool.submit(
            new Callable<String>() {
                public String call() throws Exception {
                    Thread.sleep(2000);
                        return "hello";
                };
            }
    );
    System.out.println("等待结果");
    //这里应该有trycatch
    System.out.println("拿到结果:" + future.get());
}

结果不再赘述。

多个任务

public static void main(String[] args) {

        ExecutorService threadPool2 =  Executors.newFixedThreadPool(10);
        CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool2);
        for(int i=1;i<=10;i++){
            final int seq = i;
            completionService.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    Thread.sleep(new Random().nextInt(5000));
                    return seq;
                }
            });
        }
        for(int i=0;i<10;i++){
            System.out.println(completionService.take().get());
            //上面本应该有trycatch
        }
        threadPool2.shutdown();

    }

运行结果

3

9

1

6

8

4

7

10

5

2

这句话completionService.take().get()具体是干什么的?

举个例子,你种了10亩地的麦子,等到秋天的时候,你如何割麦子呢?

当然是看那10亩地,那一亩先成熟,就先收割那一亩对吧。

completionService.submit了10个任务,completionService本身也不知道那个任务先执行完。completionService.take()就是获得已经执行完的那个任务的Future。

关于completionservice大家还可以看看下面这个资料

使用CompletionService批处理任务

感谢glt

参考资料

http://blog.csdn.net/ghsau/article/details/7451464

Callable与Future的更多相关文章

  1. java多线程系类:JUC线程池:06之Callable和Future(转)

    概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...

  2. Java多线程系列--“JUC线程池”06之 Callable和Future

    概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...

  3. Java线程(七):Callable和Future

    转自:http://blog.csdn.net/ghsau/article/details/7451464 本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果. C ...

  4. Java并发编程:Callable、Future和FutureTask

    作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...

  5. 【原创】JAVA并发编程——Callable和Future源码初探

    JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...

  6. Java多线程21:多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask

    CyclicBarrier 接着讲多线程下的其他组件,第一个要讲的就是CyclicBarrier.CyclicBarrier从字面理解是指循环屏障,它可以协同多个线程,让多个线程在这个屏障前等待,直到 ...

  7. Callable、Future、RunnableFuture、FutureTask的原理及应用

    1. Callable.Future.RunnableFuture.FutureTask的继承关系 在多线程编程中,我们一般通过一个实现了Runnable接口的对象来创建一个线程,这个线程在内部会执行 ...

  8. 并发编程 05—— Callable和Future

    Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...

  9. java核心知识点学习----创建线程的第三种方式Callable和Future CompletionService

    前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的. Call ...

  10. Java并发(8):CountDownLatch、CyclicBarrier、Semaphore、Callable、Future

    CountDownLatch.CyclicBarrier.Semaphore.Callable.Future  都位于java.util.concurrent包下,其中CountDownLatch.C ...

随机推荐

  1. 在一维坐标轴上有n个区间段,求重合区间最长的两个区间段。

    //重叠区间数 #define N 2 typedef struct arrange { int x; int y; } Arrange; //先按左边界排序,若相等再按右边界排序(升序) int c ...

  2. SRAM/DRAM,PROM/EPROM/EEPROM,NOR/NAND FLASH区别

                          SRAM/DRAM,PROM/EPROM/EEPROM,NOR/NAND FLASH区别 RAM / ROM 存储器 ROM和RAM指的都是半导体存储器,R ...

  3. RxJava(一) create操作符的用法和源码分析

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/51524470 本文出自:[余志强的博客] 1 create操作符的基 ...

  4. Linux下C/C++程序调试基础(GCC,G++,GDB,CGDB,DDD)

    在写程序的时候,经常会遇到一些问题,比如某些变量计算结果不是我们预期的那样,这时我们需要对程序进行调试.本文主要介绍调试C/C++在Linux操作系统下主要的调试工具. 在Linux下写程序,C/C+ ...

  5. android 集成微博常见问题

    我们在做微博集成登录.分享.聊天的时候,肯定会遇到很多的坑,这里总结下常见的问题. 文件不存在 C8998 的解决方法 如图我们走微博授权登录的时候如果OAuth2.0 授权设置回调页面设置和本地的不 ...

  6. Gazebo機器人仿真學習探索筆記(一)安裝與使用

    Gazebo提供了多平臺的安裝和使用支持,大部分主流的linux,Mac以及Windows,這裏結合ROS以Ubuntu爲例進行介紹. 首先是參考資料:http://gazebosim.org/tut ...

  7. Storm并发机制详解

    本文可作为 <<Storm-分布式实时计算模式>>一书1.4节的读书笔记 在Storm中,一个task就可以理解为在集群中某个节点上运行的一个spout或者bolt实例. 记住 ...

  8. TraceView性能分析工具介绍

    一.TraceView简介 TraceView是AndroidSDK里面自带的工具,用于对Android的应用程序以及Framework层的代码进行性能分析. TraceView是图形化的工具,最终它 ...

  9. UNIX网络编程——epoll的 et,lt关注点

           epoll模型有两种工作模式,ET和LT两种模式下都有一些细节值得注意,以下是一些思考:   一.ET模式下 Q1:调用accept时,到底TCP完成队列里有多少个已经建立好的连接? 这 ...

  10. Dynamics CRM2011 MspInstallAction failed when installing an Update Rollup

    今天在给客户做环境迁移,安装包完成后按惯例打补丁,但在打补丁的时候却报错了,错误如下 最开始怀疑第一个打6是不是不对,毕竟N久没碰2011了忘的差不多了,后来下了个rollup1居然也打不上,根据这个 ...