Callable,Runnable异同
1、Runnable和Callable的区别
(1) Callable规定的方法是 call(), Runnable规定的方法是 run()。
(2) Callable的任务执行后可返回值,而 Runnable的任务是不能返回值。
(3) call方法可以抛出异常, run方法不可以。
(4)运行 Callable任务可以拿到一个 Future对象
Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get方法来获取结果,如果线程没有执行完, Future.get()方法可能会阻塞当前线程的执行;如果线程出现异常, Future.get()会 throws InterruptedException或者 ExecutionException;如果线程已经取消,会跑出 CancellationException。取消由 cancel方法来执行。
isDone确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future但又不提供可用的结果,则可以声明 Future <?> 形式类型、并返回null作为底层任务的结果。
Future接口的定义如下:
Future模式在请求发生时,会先产生一个 Future凭证给发出请求的客户,它的作用就像是 Proxy物件,同时,由一个新的执行线程持续进行目标物件的生成( Thread - Per - Message),真正的目标物件生成之后,将之设定至 Future之中,而当客户端真正需要目标物件时,目标物件也已经准备好,可以让客户提取使用。
结合 JDK的 Future来看,就是你 run线程后,你可以把线程的返回值赋给 Future并返回一个 Future对象。这时你可以立即拿到这个对象,然后进行下面的逻辑。但是如果你要 get这个 Future中的线程结果,就会被阻塞直到线程结束。
相当于现在的期房,你把手续和钱都交上去了,就可以马上拿到合同,但只有合同没有房子。这个时候你已经是有房一族了,你可以先去买家电买装修(走下面的其他逻辑)。但是你要把家电和装修放进去,就必须等到房子完工(阻塞)。
2、Callable实现:
submit方法会产生Future对象,它用Callable返回结果的特定类型进行了参数化,可以用isDone()的方法来查询Future是否已经完成。当任务完成是,它具有一个结果,可以调用get()方法来获取该结果。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
package zeze; import java.util.ArrayList;import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future; /*** * * @ClassName: EbayMultiplyThreadCheck * @Description: TODO * @author zeze * @date 2017年2月16日 上午8:49:46 * */public class EbayMultiplyThreadCheck { public static void main(String[] args) { ExecutorService exec = Executors.newFixedThreadPool(10); ArrayList<Future<String>> results = new ArrayList<Future<String>>(); for (int i = 0; i < 10; i++) { String email = "asd" + i + "@qq.com"; results.add(exec.submit(new TaskWithResult(email))); } boolean isDone = false; while (!isDone) { isDone = true; for (Future<String> future : results) { if (!future.isDone()) { isDone = false; try { Thread.sleep(1000); } catch (InterruptedException e) { } break; } } } exec.shutdown(); }} class TaskWithResult implements Callable<String> { private String email; public TaskWithResult(String email) { this.email = email; } @Override public String call() { System.out.println(email); return null; } } |
3、Runnable 实现
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
/** * @Title: RunnableDemo.java* @Package zeze* @Description: TODO(用一句话描述该文件做什么)* @author A18ccms A18ccms_gmail_com * @date 2017年3月13日 下午4:08:09* @version V1.0 */package zeze; import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors; import javafx.animation.Animation.Status; /** * @ClassName: RunnableDemo * @Description: TODO * @author zeze * @date 2017年3月13日 下午4:08:09 * */public class RunnableDemo implements Runnable { protected int countDown = 10; private static int taskCount = 0; private final int id = taskCount++; public RunnableDemo() { } public RunnableDemo(int countDown) { this.countDown = countDown; } public String status() { return "#" + id + "(" + (countDown > 0 ? countDown : "LiftOff!") + ")."; } @Override public void run() { while (countDown-- > 0) { System.out.print(status()); Thread.yield();// 将CPU从一个线程转移给另一个线程 } } public static void main(String[] args) { System.out.println("这个任务的run()不是单独的线程驱动,是在main()中直接调用"); RunnableDemo launch = new RunnableDemo(); launch.run(); System.out.println(); System.out.println("************************************"); System.out.println("在新线程中启动任务"); Thread thread = new Thread(new RunnableDemo()); thread.start(); System.out.println("Waiting for LiftOff"); System.out.println("************************************"); System.out.println("添加多个线程去驱动更多的任务"); for (int i = 0; i < 5; i++) { new Thread(new RunnableDemo()).start(); } System.out.println("Waiting for LiftOff"); System.out.println("************************************"); System.out.println("使用executor"); ExecutorService exec = Executors.newCachedThreadPool(); exec=Executors.newFixedThreadPool(5); for (int i = 0; i < 5; i++) { exec.execute(new RunnableDemo()); } exec.shutdown(); } } |
Callable,Runnable异同的更多相关文章
- Callable, Runnable, Future, FutureTask
Java并发编程之Callable, Runnable, Future, FutureTask Java中存在Callable, Runnable, Future, FutureTask这几个与线程相 ...
- Callable,Runnable比较及用法
http://blog.csdn.net/xtwolf008/article/details/7713580 http://www.cnblogs.com/whgw/archive/2011/09/2 ...
- Callable,Runnable的区别及用法
编写多线程程序一般有三种方法,Thread,Runnable,Callable. Runnable和Callable的区别是: (1)Callable规定的方法是call(),Runnable规定的方 ...
- java 创建线程的三种方法Callable,Runnable,Thread比较及用法
转自:http://www.chinaitlab.com/Java/line/942440.html 编写多线程程序是为了实现多任务的并发执行,从而能够更好地与用户交互.一般有三种方法,Thread, ...
- 【Java】Callable,Runnable比较及用法
1.Runnable和Callable的区别 (1) Callable规定的方法是 call(), Runnable规定的方法是 run(). (2) Callable的任务执行后可返回值,而 Run ...
- java并发编程--Runnable Callable及Future
1.Runnable Runnable是个接口,使用很简单: 1. 实现该接口并重写run方法 2. 利用该类的对象创建线程 3. 线程启动时就会自动调用该对象的run方法 通常在开发中结合Execu ...
- 深入Callable及Runnable两个接口 获取线程返回结果
今天碰到一个需要获取线程返回结果的业务场景,所以了解到了Callable接口. 先来看下下面这个例子: public class ThreadTest { public static void mai ...
- Java多线程Runnable与Callable区别与拓展
我们先来分别看一下这两个接口 Runnable: // // Source code recreated from a .class file by IntelliJ IDEA // (powered ...
- Runnable与Callable区别
相同点: 两者都是接口:(废话) 两者都可用来编写多线程程序: 两者都需要调用Thread.start()启动线程: 不同点: 两者最大的不同点是:实现Callable接口的任务线程能返回执行结果:而 ...
随机推荐
- 每日技术总结:jquery datetimepicker,微博QQ好友QQ空间微信等分享接口
前言: 1.jquery datetimepicker 今天遇到一个日期控件格式的问题,默认选中显示的并不是设定的值,而是当天的日期.于是去查了一遍文档. 参考文章:jquery datetimepi ...
- [Angular2 Router] Auxiliary Routes bit by bit
Article Github Auxiliary Routes is is little bit hard to understand. Here is demo, link You can see ...
- [慕课笔记]mongodb入门篇
一:对mongodb有一个系统的完备的了解,只有概念清楚了,才能更好的使用 二:学会mongodb数据库的搭建 首先:了解如何部署数据库的服务 搭建简单的单机服务到搭建具有冗余容错功能的复制集再到搭建 ...
- ORACEL上传BLOB,深度遍历文件夹
// uploadingDlg.cpp : 实现文件// #include "stdafx.h"#include "uploading.h"#include & ...
- windows关闭进程 批处理端口占用
cmd 关闭进程java taskkill /F /IM java.exe taskkill /f /im java.exe 如何用dat批处理文件关闭某端口对应程序-Windows自动化命令 如何用 ...
- matlab 正则表达式
regexprep Replace text using regular expression collapse all in page Syntax newStr = regexprep(str,e ...
- 什么是网站CDN服务,CDN加速原理?
转载:http://server.zzidc.com/fwqcjwt/728.html 摘要:在为您的网站打开速度发愁吗?您有没有发现有些大网站每天拥有几十万或者上百万,甚至几亿用户的访问,而且不同用 ...
- 【2013】将x插入有序数列
Time Limit: 3 second Memory Limit: 2 MB 将一个数x插入到有序数列a中,插入后a仍然有序. Input 第一行输入有序数列a的元素个数 第二行依次输入a的元素,以 ...
- ServerSocketChannel API用法
java.nio.channels 类 ServerSocketChannel java.lang.Object java.nio.channels.spi.AbstractInterruptible ...
- [Ramda] Compose lenses
We can compose lenses to get value: const addrs = [{street: '99 Walnut Dr.', zip: '04821'}, {street: ...