实际开发过程中,我们常常需要等待一批线程都返回结果后,才能继续执行。《线程等待——CountDownLatch使用》中我们介绍了CountDownLatch的使用,通过使用CountDownLatch,可以实现线程等待。

JDK 1.8实现了一种更好的方式,实现线程等待与获取线程返回值,那就是Callable接口,下面我们来看看具体代码。

package com.coshaho.learn;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; import org.apache.kafka.common.group.Time; public class CallableLearn
{
public static void main(String[] args) throws InterruptedException, ExecutionException
{
long start = System.currentTimeMillis();
MyCallableTask task1 = new MyCallableTask();
MyCallableTask task2 = new MyCallableTask();
MyCallableTask task3 = new MyCallableTask(); // 使用线程池submit方法,可以获取返回值
Future<String> future1 = FIXED_THREADPOOL.submit(task1);
Future<String> future2 = FIXED_THREADPOOL.submit(task2);
Future<String> future3 = FIXED_THREADPOOL.submit(task3);
long end = System.currentTimeMillis(); // 任务提交不会阻塞
System.out.println("Submit task cost " + (end - start) + "ms."); System.out.println("Task1: " + future1.get());
System.out.println("Task2: " + future2.get());
System.out.println("Task3: " + future3.get()); // Future.get方法等待线程返回值
System.out.println("Get task return value cost " + (System.currentTimeMillis() - end) + "ms.");
} // 大小为3的线程池
public final static ExecutorService FIXED_THREADPOOL = Executors.newFixedThreadPool(3); public static class MyCallableTask implements Callable<String>
{
// 睡i秒并返回信息
@Override
public String call() throws Exception
{
Random random = new Random();
int i = random.nextInt(10) * 1000;
Time.sleep(i);
return "Sleep " + i + "ms.";
} } } 结果

Submit task cost 3ms.
Task1: Sleep 5000ms.
Task2: Sleep 8000ms.
Task3: Sleep 8000ms.
Get task return value cost 8659ms.

三个关键点

1、 线程需要实现Callable接口

2、 线程池采用submit方法提交任务,可以获取返回值Future

3、 使用Future.get方法时,会阻塞当前线程,等待任务返回值

Java Callable接口——有返回值的线程的更多相关文章

  1. Callable接口--有返回值的线程

    Callable java5之前是没有返回值的,Java5新增了Callable接口获得线程的返回值,可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口.Cal ...

  2. Java中使用有返回值的线程

    在创建多线程程序的时候,我们常实现Runnable接口,Runnable没有返回值,要想获得返回值,Java5提供了一个新的接口Callable,可以获取线程中的返回值,但是获取线程的返回值的时候,需 ...

  3. java使用Callable创建又返回值的线程

    并发编程使我们可以将程序分为很多个分离的,相互之间独立的任务,通过使用多线程的机制,将每个任务都会有一个执行线程来单独的驱动,一个线程是 进程中一个单一顺序控制流,一个进程可以拥有多个线程,也就相当于 ...

  4. java笔记--用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程

    用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程 ThreadLocal在我的笔记"关于线程同步"的第5种方式里面有介绍,这里就不多说了. ...

  5. Java线程中带有返回值的线程Callable

    在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了.现在Java终于有可返回值的任务(也可以叫做线程)了. 可返回值的任务必须实现C ...

  6. Java多线程-新特性-有返回值的线程

    在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了. 现在Java终于有可返回值的任务(也可以叫做线程)了. 可返回值的任务必须实现 ...

  7. Java线程:新特征-有返回值的线程

    http://lavasoft.blog.51cto.com/62575/222082/ Java线程:新特征-有返回值的线程 2009-11-04 17:33:56 标签:返回值 职场 线程 休闲 ...

  8. Java线程:新特征-有返回值的线程《转》

      原始文章   在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了.   现在Java终于有可返回值的任务(也可以叫做线程)了. ...

  9. paip.java 多线程参数以及返回值Future FutureTask 的使用.

    paip.java 多线程参数以及返回值Future FutureTask 的使用. 在并发编程时,一般使用runnable,然后扔给线程池完事,这种情况下不需要线程的结果. 所以run的返回值是vo ...

随机推荐

  1. C++ Error : initial value of reference to non-const must be an lvalue

    如下这段代码,编译报错: Error : initial value of reference to non-const must be an lvalue #include <iostream ...

  2. Mac - Hexo+GitHub轻松搭建自己的博客

    Hexo 是一个快速.简洁且高效的博客框架.Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页.官方文档传送门.Hexo的安装是个很快速简便的过程,但 ...

  3. 使用pidstat监控资源使用

    linux可以使用pidstat命令监控系统资源,比如监控cup使用如下: pidstat -u 还可以使用 -r(内存) -d(硬盘)

  4. 设置ubuntu默认中文字符

    一. Ubuntu默认的中文字符编码 Ubuntu默认的中文字符编码为zh_CN.UTF-8,这个可以在 /etc/environment中看到:sudo gedit /etc/environment ...

  5. .NET程序运行过程

    ASP.NET http请求 - IIS - isapi.dll - CLR(com服务通信初始化CLR - AppDomain - 加载程序集 - JIT译 - 本地机器码 - 内存 - CPU 执 ...

  6. HIT 2715 - Matrix3 - [最小费用最大流][数组模拟邻接表MCMF模板]

    题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=2715 Time limit : 5 sec Memory limit : 64 M Zhouguyue ...

  7. tkinter 提示符

    在python3.4中,原来的tkMessageBox变成tkinter.messagebox,使用方式如下: import tkinter.messagebox tkinter.messagebox ...

  8. js里常用函数之高阶函数

    高阶函数:将函数作为参数或者返回值的函数.将函数作为参数的用法通常称作回调函数,函数参数通常会在主函数被执行之后被高阶函数调用. 高阶函数的使用实例.可以把有相似操作的函数用一个高阶函数来重构,精简代 ...

  9. JS中"属性"的用法

    JS的属性和C#有相似之处  ! 使用get和set来进行属性的获取和设置 var obj={ a:"1", get age(){ return obj.a; }, set age ...

  10. Spark-Cache与Checkpoint

    一.Cache缓存操作 scala> val rdd1 = sc.textFile("hdfs://192.168.146.111:9000/logs") rdd1: org ...