本文可作为传智播客《张孝祥-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. Ajax+Struts2实现验证码验证功能

    ---------------------------------------------------------------------------------------------------- ...

  2. AFNetworking详解和相关文章链接

    写在开头: 作为一个iOS开发,也许你不知道NSUrlRequest.不知道NSUrlConnection.也不知道NSURLSession...(说不下去了...怎么会什么都不知道...)但是你一定 ...

  3. JavaMail API 概述

    JavaMail API提供了一种与平台无关和协议独立的框架来构建邮件和消息应用程序. JavaMail API提供了一组抽象类定义构成一个邮件系统的对象.它是阅读,撰写和发送电子信息的可选包(标准扩 ...

  4. 22 Notification 通知栏代码

    结构图: MainActivity.java package com.qf.day22_notification; import android.app.Activity; import androi ...

  5. Android加速度传感器

    Android加速度传感器 效果图 手机平放桌面的两张截屏,数据一直在刷新 源码 下载地址(Android Studio工程):http://download.csdn.net/detail/q487 ...

  6. ROS(indigo)ABB机器人MoveIt例子

    ROS(indigo)ABB机器人例子 参考网址: 1  http://wiki.ros.org/Industrial 2  http://wiki.ros.org/abb 3  https://gi ...

  7. HTML5中 HTML表单和PHP环境搭建及与PHP交互 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博! 知识点概括:HTML表单/PHP环境搭建/表单提交数据与PHP交互 第一部分:HTML表单 <!DOCTYP ...

  8. 1068. Find More Coins (30)

    题目如下: Eva loves to collect coins from all over the universe, including some other planets like Mars. ...

  9. Android初级教程获取手机位置信息GPS与动态获取最佳方式

    简单介绍一下gps定位的操作. 主要是靠locationmanger这个api完成的一些操作:通过获取这个实例,然后调用它的requestLocationUpdates方法进行注册.传入的参数分别有以 ...

  10. Android初级教程启动定时器详解

    本案例知识是:后台执行定时任务. Alarm机制: 一.创建LongRunningService类 package com.example.servicebestpractice; import ja ...