`
zsj01005432
  • 浏览: 43110 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

【转】 Runnable、Callable、Executor、Future关系解读

    博客分类:
  • java
 
阅读更多
【本文原地址为:http://blog.csdn.net/zhangzhaokun/article/details/6615454】

在再度温习Java5的并发编程的知识点时发现,首要的就是把Runnable、Callable、Executor、Future等的关系搞明白,遂有了下述小测试程序,通过这个例子上述三者的关系就一目了然了。

简单来说,Executor就是Runnable和Callable的调度容器,Future就是对于具体的调度任务的执行结果进行查看,最为关键的是Future可以检查对应的任务是否已经完成,也可以阻塞在get方法上一直等待任务返回结果。Runnable和Callable的差别就是Runnable是没有结果可以返回的,就算是通过Future也看不到任务调度的结果的。

/** 
 * 通过简单的测试程序来试验Runnable、Callable通过Executor来调度的时候与Future的关系 
 */  
package com.hadoop.thread;  
  
import java.util.concurrent.Callable;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Future;  
  
public class RunnableAndCallable2Future {  
  
    public static void main(String[] args) {  
  
        // 创建一个执行任务的服务  
        ExecutorService executor = Executors.newFixedThreadPool(3);  
        try {  
            //1.Runnable通过Future返回结果为空  
            //创建一个Runnable,来调度,等待任务执行完毕,取得返回结果  
            Future<?> runnable1 = executor.submit(new Runnable() {  
                @Override  
                public void run() {  
                    System.out.println("runnable1 running.");  
                }  
            });  
            System.out.println("Runnable1:" + runnable1.get());  
  
            // 2.Callable通过Future能返回结果  
            //提交并执行任务,任务启动时返回了一个 Future对象,  
            // 如果想得到任务执行的结果或者是异常可对这个Future对象进行操作  
            Future<String> future1 = executor.submit(new Callable<String>() {  
                @Override  
                public String call() throws Exception {  
                    // TODO Auto-generated method stub  
                    return "result=task1";  
                }  
            });  
            // 获得任务的结果,如果调用get方法,当前线程会等待任务执行完毕后才往下执行  
            System.out.println("task1: " + future1.get());  
  
            //3. 对Callable调用cancel可以对对该任务进行中断  
            //提交并执行任务,任务启动时返回了一个 Future对象,  
            // 如果想得到任务执行的结果或者是异常可对这个Future对象进行操作  
            Future<String> future2 = executor.submit(new Callable<String>() {  
                @Override  
                public String call() throws Exception {               
                    try {  
                        while (true) {  
                            System.out.println("task2 running.");  
                            Thread.sleep(50);  
                        }  
                    } catch (InterruptedException e) {  
                        System.out.println("Interrupted task2.");  
                    }  
                    return "task2=false";  
                }  
            });  
              
            // 等待5秒后,再停止第二个任务。因为第二个任务进行的是无限循环  
            Thread.sleep(10);  
            System.out.println("task2 cancel: " + future2.cancel(true));  
  
            // 4.用Callable时抛出异常则Future什么也取不到了  
            // 获取第三个任务的输出,因为执行第三个任务会引起异常  
            // 所以下面的语句将引起异常的抛出  
            Future<String> future3 = executor.submit(new Callable<String>() {  
  
                @Override  
                public String call() throws Exception {  
                    throw new Exception("task3 throw exception!");  
                }  
  
            });  
            System.out.println("task3: " + future3.get());  
        } catch (Exception e) {  
            System.out.println(e.toString());  
        }  
        // 停止任务执行服务  
        executor.shutdownNow();  
    }  
}  


执行结果如下:

runnable1 running.  
Runnable1:null  
task1: result=task1  
task2 running.  
task2 cancel: true  
Interrupted task2.  
java.util.concurrent.ExecutionException: java.lang.Exception: Bad flag value!  
分享到:
评论

相关推荐

    Java中的Runnable,Callable,Future,FutureTask的比较

    Java中的Runnable、Callable、Future和FutureTask是Java多线程编程中的核心概念,它们各自扮演着不同的角色,共同协作以实现并发任务的管理和执行。 1. **Runnable**: Runnable是最基本的多线程接口,它只有一个`...

    Java使用Callable和Future创建线程操作示例

    "Java使用Callable和Future创建线程操作示例" Java使用Callable和Future创建线程操作示例主要介绍了Java使用Callable和Future创建线程操作,结合实例形式分析了java使用Callable接口和Future类创建线程的相关操作...

    Android(Java)之多线程结果返回——Future 、FutureTask、Callable、Runnable

    4. `FutureTask`: `FutureTask`结合了`Runnable`和`Future`的功能,它可以包装一个`Callable`对象,并作为`Runnable`提交给`Executor`,同时它也是一个`Future`,可以用来获取计算结果。创建`FutureTask`的示例: `...

    Callable:Callable与Future在Web应用中的优化案例

    在Java编程中,Callable接口和Future接口是多线程编程中的重要工具,它们在Web应用程序的性能优化中扮演着关键角色。本篇文章将深入探讨Callable和Future如何在Web应用中提高效率并优化资源利用。 Callable接口是...

    JAVA中Callable的使用

    与Runnable接口相比,Callable接口提供了更强大的功能,因为Runnable只能定义无返回值的任务,而Callable可以定义有返回值的任务。这篇教程将深入探讨如何在Java中使用Callable。 Callable接口位于`java.util....

    并发编程之Executor线程池原理与源码解读.pdf

    submit()方法可以用来提交Callable或Runnable任务,并返回一个Future对象,通过这个Future对象可以检查任务是否完成,或者获取任务执行的结果;shutdown()方法用于关闭线程池,不再接受新提交的任务,但会完成所有已...

    Executor框架使用详解

    `FutureTask`类实现了`Future`和`Runnable`,可以用来包装`Callable`任务并提交给`ExecutorService`。 标签中提到的“源码”意味着深入理解Executor框架的实现原理是重要的。例如,理解`ThreadPoolExecutor`如何...

    Executor,Executors,ExecutorService比较.docx

    - **submit(Callable)**:提交一个`Callable`任务,同样返回`Future`对象,`Callable`的任务可以有返回值。 - **invokeAny**(Collection&lt;Callable&lt;T&gt;&gt; tasks)**:在给定的任务列表中,选择并执行一个任务,返回其...

    线程池之Executor框架.docx

    - **任务**:Executor框架处理的主要对象是任务,任务可以是实现`Runnable`接口的实例,也可以是实现`Callable`接口的实例。`Runnable`接口的任务没有返回值,而`Callable`接口的任务可以返回一个结果。 - **任务...

    Java中Future、FutureTask原理以及与线程池的搭配使用

    `Future`接口提供了对异步计算结果的访问和控制,而`FutureTask`是`Future`的一个具体实现,它还同时实现了`Runnable`接口,因此可以直接提交给`Executor`执行。 `Future`接口提供了以下方法: 1. `boolean cancel...

    Java多线程实现的四种方式

    在Java中,实现多线程有四种主要方法:继承Thread类、实现Runnable接口、使用ExecutorService和使用Callable与Future。下面将详细探讨这四种方式。 1. 继承Thread类 在Java中,我们可以直接继承Thread类并重写其run...

    JAVA多线程实现的四种方式 - FelixZh - 博客园1

    在Java中,实现多线程有四种主要方式:继承Thread类、实现Runnable接口、使用ExecutorService和使用Callable与Future。下面将详细阐述这四种方式。 1. 继承Thread类 当你需要创建一个新的线程类时,可以继承Thread...

    Java特别篇-关于线程创建的三种方式的总结对比

    - `Callable`与`Runnable`相似,但其主要区别在于`Callable`的`call()`方法可以返回一个结果并可能抛出异常。 - `Future`接口提供了获取计算结果的方法,包括阻塞等待结果或取消尚未完成的任务。 - 使用`...

    java并发编程:Executor、Executors、ExecutorService.docx

    Executor是一个接口,它定义了一个核心方法`executor(Runnable command)`,用于接收实现了Runnable接口的任务对象并执行。Executor的主要目的是抽象出线程的创建和管理,让开发者只需关注任务本身,而无需关心线程的...

    Java多线程之Executor框架.docx

    例如,使用`ExecutorService.submit(Callable)`或`ExecutorService.submit(Runnable)`方法,会返回一个`Future`对象,可以用来检查任务状态、取消任务或获取结果。 总的来说,Java的Executor框架通过引入线程池和...

    Android Executor线程池

    2. 使用`Future`和`Callable`获取任务结果:这允许你在任务执行完成后获取返回值,而`Runnable`只能表示无返回值的任务。 3. 使用`shutdown()`和`awaitTermination()`优雅地关闭线程池:在应用退出时,确保正确关闭...

    JAVA多线程实现和应用总结

    Future&lt;Integer&gt; future1 = executor.submit(new Task(10)); Future&lt;Integer&gt; future2 = executor.submit(new Task(20)); System.out.println("Task 1 result: " + future1.get()); System.out.println("Task 2...

    Java多线程之异步Future机制的原理和实现共5页.p

    1. **使用FutureTask**:FutureTask是一个实现了RunnableFuture接口的类,它既可以作为Runnable被Executor执行,又可以作为Future获取结果。你可以直接创建一个FutureTask,传入Callable任务,然后提交给...

    四种方式实现线程

    // 提交Callable任务,返回Future executor.shutdown(); // 关闭线程池 ``` ExecutorService提供了线程池管理,可以控制并发数量,优化系统资源利用率。 以上四种方式各有优缺点。Thread类适合简单的线程需求,...

    java面试精华14

    本文将深入探讨如何利用Java提供的`Runnable`与`Callable`接口配合`Future`或`FutureTask`来实现这一功能。 #### 一、基础知识回顾 在开始之前,我们先简要回顾一下`Runnable`和`Callable`这两个接口的基本概念: ...

Global site tag (gtag.js) - Google Analytics