本文可作为传智播客《张孝祥-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. C算法实现:将字符串中的数字返回为整型数

    今天看linux内核驱动的代码,发现一个算法写得挺简单,也有意思. 分享一下我的测试代码: #include <stdio.h> typedef int U32 ; U32 String2 ...

  2. Java异常处理-----java异常体系

    再三思考后还是决定贴图,csdn的格式,我是真玩不转,对不起了各位,继续将就吧. 错误原因:内存溢出.需要的内存已经超出了java虚拟机管理的内存范围. 错误原因:找不到类文件. 错误(Error): ...

  3. JBOSS EAP 6 系列五 Managed domains 管理域最主要的功能是“统一部署,统一配置”

    摘要 本文首先介绍Managed Domain的概念,管理域最主要的功能是"统一部署,统一配置".接下来通过一个实例在"统一配置"部分实现一个双机配置起来的域, ...

  4. spark shuffle

    Spark Shuffle 1. Shuffle相关 当Map的输出结果要被Reduce使用时,输出结果需要按key哈希,并且分发到每一个Reducer上去,这个过程就是shuffle.由于shuff ...

  5. Shell 整数比较、字符串比较

    整数比较  -eq       等于,如:if [ "$a" -eq "$b" ]  -ne       不等于,如:if [ "$a" - ...

  6. TortoiseSVN文件夹图标不显示

    伴随着十二月的脚步,小编带领的市委组织部项目有条不紊的进行着,在最近的项目中遇到一个问题TortoiseSVN文件夹的图标不显示,为什么小编已经安装好TortoiseSVN了,发现文件夹的图标还是系统 ...

  7. (九十七)集成JPush实现远程通知和推送的发送

    上节介绍了通过直接和APNS交互实现推送的方法,较为繁琐,最为重要的是发送推送需要特定的服务端,通过JPush,不仅可以简化客户端的接收,还可以通过控制台或者API实现通知的发送. 首先注册JPush ...

  8. javaRMI详解

    前几天在阿里内推一面的时候,面试官问到了一个关于java中RMI(Remote Method Invocation)的问题,当时感觉自己回答的还比较好,他比较满意,但那是因为他问的比较浅,所以自己看了 ...

  9. Oracle Metalink Notes Collection

    INV Note 123456.1 Latest 11i Applications Recommended Patch List Note 568012.1:FAQ: Inventory Standa ...

  10. windbg分析运行在64位环境下的32位程序的dump

    windbg命令如下 1.   .load wow64exts 2.   !sw 3.   ~* kvnf