本文可作为传智播客《张孝祥-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. Swift中的可选协议和方法的历史渊源

    @objc protocol Transaction { func commit() -> Bool optional func isComplete() -> Bool } 以上协议被标 ...

  2. Lua热更新(hotfix)

    Lua热更新(hotfix)(金庆的专栏)hotfixLua 5.2/5.3 hotfix. Hot update functions and keep old data.https://github ...

  3. Java异常处理-----自定义异常

    自定义异常 问题:现实中会出现新的病,就需要新的描述. 分析: java的面向对象思想将程序中出现的特有问题进行封装. 案例: 定义功能模拟凌波登录.(例如:lb(String ip))需要接收ip地 ...

  4. Java中synchronized的使用实例

    一.使用场景 在负责后台开发的时候,很多时候都是提供接口给前端开发人员去调用,会遇到这样的场景: 需要提供一个领奖接口,每个用户名只能领取一次,我们可以将成功领取的用户在数据库用个标记保存起来.如果这 ...

  5. Linux 高性能服务器编程——Linux网络编程基础API

    问题聚焦:     这节介绍的不仅是网络编程的几个API     更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系.     这节主要介绍三个方面的内容:套接字(so ...

  6. MAMP显示文件列表

    背景 MAMP是Mac下的一个PHP+Nginx+MySQL的集成环境,支持多站点,不同版本PHP. 今天有人请教MAMP如何显示文件列表的问题,这里记录一下. 知识补充 一个网站为了安全考虑,默认是 ...

  7. CUSTOM.PLL的使用

    在开发中对系统标准form的修改一般不建议修改系统原有FORM,对所需要修改的内容一般写在CUSTOM.PLL里即可,应为每个form运行的时候都会调用CUSTOM.PLL具体概念性东西可参考网上资料 ...

  8. java虚拟机 jvm java堆 方法区 java栈

    java堆是java应用程序最密切的内存空间.几乎所有的对象都存在堆中.java堆完全自动化管理,通过垃圾回收机制,垃圾对象会自动清理,不需要显式释放. 根据java垃圾回收机制的不同,java堆可能 ...

  9. DFS(深度优先)算法编程实践

    DFS定义 DFS(Depth-First-Search)深度优先搜索算法,是搜索算法的一种.是一种在开发爬虫早期使用较多的方法.它的目的是要达到被搜索结构的叶结点 . 特点 每次深度优先搜索的结果必 ...

  10. python跨行 print:多用(),换行符\要小心,少用+或者不用(其它程序代码跨行用\就行,不能用括号)

    这两种是错的 # print '11' #       'tset3'#error # print '12' #       +'tset4'#error python跨行用()和\都能实现.+只是连 ...