Callable, Runnable, Future, FutureTask
Java并发编程之Callable, Runnable, Future, FutureTask
Java中存在Callable, Runnable, Future, FutureTask这几个与线程相关的类或接口, 下面来了解一下它们的作用和区别.
一.Callable和Runnable
Callable和Runnable类似, 实现Callable和Runnable接口的类都是可以被其他线程运行的任务, Callable和Runnable主要有以下几点区别:
(1). Callable中声明的方法是call(), Runnable中声明的方法是run().
(2). Callable任务执行后可返回值, Runnable任务执行后没有返回值.
(3). call()方法可以抛出异常, run()方法不能抛出异常.
(4). 运行Callable任务可以拿到一个Future对象.
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
二. Future对象
Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果、设置结果操作。可以通过get()方法获取执行结果, get()方法会阻塞,直到任务返回结果
public interface Future<V> {
/**
* Attempts to cancel execution of this task. This attempt will
* fail if the task has already completed, has already been cancelled,
* or could not be cancelled for some other reason. If successful,
* and this task has not started when <tt>cancel</tt> is called,
* this task should never run. If the task has already started,
* then the <tt>mayInterruptIfRunning</tt> parameter determines
* whether the thread executing this task should be interrupted in
* an attempt to stop the task.
*
* <p>After this method returns, subsequent calls to {@link #isDone} will
* always return <tt>true</tt>. Subsequent calls to {@link #isCancelled}
* will always return <tt>true</tt> if this method returned <tt>true</tt>.
*
* @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
* task should be interrupted; otherwise, in-progress tasks are allowed
* to complete
* @return <tt>false</tt> if the task could not be cancelled,
* typically because it has already completed normally;
* <tt>true</tt> otherwise
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
* Returns <tt>true</tt> if this task was cancelled before it completed
* normally.
*/
boolean isCancelled();
/**
* Returns <tt>true</tt> if this task completed.
* Completion may be due to normal termination, an exception, or
* cancellation -- in all of these cases, this method will return
* <tt>true</tt>.
*/
boolean isDone();
/**
* Waits if necessary for the computation to complete, and then
* retrieves its result.
*/
V get() throws InterruptedException, ExecutionException;
/**
* Waits if necessary for at most the given time for the computation
* to complete, and then retrieves its result, if available.
*/
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
下面依次解释每个方法的作用:
- cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数 mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如 果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返 回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若 mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论 mayInterruptIfRunning为true还是false,肯定返回true。
- isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
- isDone方法表示任务是否已经完成,若任务完成,则返回true;
- get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
- get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
也就是说Future提供了三种功能:
1)判断任务是否完成;
2)能够中断任务;
3)能够获取任务执行结果。
因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask。
三. FutureTask
我们先来看一下FutureTask的实现:
public class FutureTask<V> implements RunnableFuture<V> {
}
FutureTask类实现了RunnableFuture接口,我们看一下RunnableFuture接口的实现:
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
FutureTask提供了2个构造器:
public FutureTask(Callable<V> callable) {
}
public FutureTask(Runnable runnable, V result) {
}
事实上,FutureTask是Future接口的一个唯一实现类
简单示例:
import java.util.concurrent.*;
/**
* Created by xinfengyao on 16-2-17.
*/
public class RunnableFutureTest {
static ExecutorService executorService = Executors.newCachedThreadPool();
public static void main(String[] args) throws ExecutionException, InterruptedException {
runnableDemo();
futureDemo();
}
/**
* Runnable无返回值
*/
static void runnableDemo() {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("runnable demo: " + fibc(20));
}
}).start();
}
/**
* 其中Runnable实现的是void run()方法,无返回值;Callable实现的是 V
* call()方法,并且可以返回执行结果。其中Runnable可以提交给Thread来包装下
* ,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。
*/
static void futureDemo() throws ExecutionException, InterruptedException {
/**
* 提交runnable则没有返回值, future没有数据
*/
Future<?> result = executorService.submit(new Runnable() {
@Override
public void run() {
fibc(20);
}
});
System.out.println("future result from runnable: " + result.get());
/**
* 提交Callable, 有返回值, future中能够获取返回值
*/
Future<Integer> result2 = executorService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return fibc(20);
}
});
System.out.println("future result from callable: " + result2.get());
/**
* FutureTask则是一个RunnableFuture<V>,既实现了Runnable又实现了Future<V>这两个接口,
* 另外它还可以包装Runnable(实际上会转换为Callable)和Callable
* <V>,所以一般来讲是一个复合体了,它可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行
* ,并且还可以通过v get()返回执行结果,在线程体没有执行完成的时候,主线程一直阻塞等待,执行完则直接返回结果。
*/
FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return fibc(20);
}
});
// 提交futureTask
executorService.submit(futureTask);
System.out.println("future result from futureTask: " + futureTask.get());
}
static int fibc(int n) {
if (n==0 || n==1) {
return n;
}
return fibc(n-1) + fibc(n-2);
}
}
运行结果:
runnable demo: 6765 future result from runnable: null future result from callable: 6765 future result from futureTask: 6765
Callable, Runnable, Future, FutureTask的更多相关文章
- Callable和Future、FutureTask的使用
http://www.silencedut.com/2016/06/15/Callable%E5%92%8CFuture%E3%80%81FutureTask%E7%9A%84%E4%BD%BF%E7 ...
- Runnable、Callable、Future和FutureTask用法
http://www.cnblogs.com/dolphin0520/p/3949310.html java 1.5以前创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable ...
- Java中的Runnable、Callable、Future、FutureTask的区别
本文转载自:http://blog.csdn.net/bboyfeiyu/article/details/24851847 Runnable 其中Runnable应该是我们最熟悉的接口,它只有一个ru ...
- 多线程-Thread,Runnable,Callable,Future,RunnableFuture,FutureTask
类图: 先看各自的源码: public interface Runnable { public abstract void run(); } public class Thread implement ...
- Runnable、Callable、Future和FutureTask之一:基本用法
Java从发布的第一个版本开始就可以很方便地编写多线程的应用程序,并在设计中引入异步处理.Thread类.Runnable接口和Java内存管理模型使得多线程编程简单直接.但正如之前提到过的,Thre ...
- Runnable、Callable、Future和FutureTask之二:源码解析
一.Callable与Future类图 1.类图 许多任务实际上都是存在延迟的计算,对于这些任务,Callable是一种更好的抽象:它会返回一个值,并可能抛出一个异常.Callable接口: V ca ...
- Java中的Runnable、Callable、Future、FutureTask的区别与示例
Java中存在Runnable.Callable.Future.FutureTask这几个与线程相关的类或者接口,在Java中也是比较重要的几个概念,我们通过下面的简单示例来了解一下它们的作用于区别. ...
- Android进阶——多线程系列之Thread、Runnable、Callable、Future、FutureTask
多线程一直是初学者最抵触的东西,如果你想进阶的话,那必须闯过这道难关,特别是多线程中Thread.Runnable.Callable.Future.FutureTask这几个类往往是初学者容易搞混的. ...
- Java并发编程:Callable、Future和FutureTask
作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...
随机推荐
- window.cookie
本地测试cookie用火狐来测试 首先cookie是document上的一个属性. 先弹出一个cookie alert(document.cookie); //弹出是空的 设置cookie,格式是有一 ...
- csuoj 1111: 三家人
acm.csu.edu.cn/OnlineJudge/problem.php?id=1111 1111: 三家人 Time Limit: 1 Sec Memory Limit: 128 MBSubm ...
- java dom4j写入XML
引用的两个jar包 dom4j-1.6.1.jar jaxen.jar //=========================代码 import java.io.FileWriter;import j ...
- SpringMVC配制全局的日期格式
SpringMVC文件配制: <mvc:annotation-driven> <!-- 处理responseBody 里面日期类型 --> <mvc:message-co ...
- Multi-voltage和power gating的实现
power domain:一个逻辑的集合体,包含power supply的一些信息.建立在FE. voltage area:chip上的一块物理区域.可以看作power domain的物理实现. Le ...
- MySQL增删改查
C/S:Client ServerB/S:Brower Server php主要实现B/S .net IIS java TomCat LAMP: Linux系统 A阿帕奇服务器 Mysql数据库 Ph ...
- 关于archlinux下的ralink5370网卡
驱动此网卡要使用 rt2800usb,rt2800lib 这两个模块 顺便说一下对模块进行操作的命令: rmmod 模块名 //为移除模块 insmod 模块所在路径 //为添加模块 查看网卡是否能被 ...
- 【py网页】sitecopy代码
001 #coding:utf-8 002 import re,os,shutil,sys 003 import urllib2,socket,cookielib 004 from threading ...
- Visual studio 中编译错误SQL71006: Only one statement is allowed per batch. A batch separator, such as 'GO', might be required between statements.
把写好的sql脚本,并在mssqlmanager里面编译成功的存储过程脚本复制到vs项目下,出现错误信息如下:SQL71006: Only one statement is allowed per b ...
- Sublime怎样新建HTML文档
1.在右下角有个plain text的标志,点击,选择文件类型为HTML 2.保存为HTML文档 3.这时候输入"!"(注意一定要选择对输入法) 4.然后按"Tab&qu ...