Java多线程编程:Callable、Future和FutureTask浅析(多线程编程之四)
java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)
java&android线程池-Executor框架之ThreadPoolExcutor&ScheduledThreadPoolExecutor浅析(多线程编程之三)
Java多线程:Callable、Future和FutureTask浅析(多线程编程之四)
通过前面几篇的学习,我们知道创建线程的方式有两种,一种是实现Runnable接口,另一种是继承Thread,但是这两种方式都有个缺点,那就是在任务执行完成之后无法获取返回结果,那如果我们想要获取返回结果该如何实现呢?还记上一篇Executor框架结构中提到的Callable接口和Future接口吗?,是的,从JAVA SE 5.0开始引入了Callable和Future,通过它们构建的线程,在任务执行完成后就可以获取执行结果,今天我们就来聊聊线程创建的第三种方式,那就是实现Callable接口。
- public interface Runnable {
- public abstract void run();
- }
而Callable的接口定义如下
- public interface Callable<V> {
- V call() throws Exception;
- }
该接口声明了一个名称为call()的方法,同时这个方法可以有返回值V,也可以抛出异常。嗯,对该接口我们先了解这么多就行,下面我们来说明如何使用,前篇文章我们说过,无论是Runnable接口的实现类还是Callable接口的实现类,都可以被ThreadPoolExecutor或ScheduledThreadPoolExecutor执行,ThreadPoolExecutor或ScheduledThreadPoolExecutor都实现了ExcutorService接口,而因此Callable需要和Executor框架中的ExcutorService结合使用,我们先看看ExecutorService提供的方法:
- <T> Future<T> submit(Callable<T> task);
- <T> Future<T> submit(Runnable task, T result);
- Future<?> submit(Runnable task);
- public static Callable<Object> callable(Runnable task)
- public static <T> Callable<T> callable(Runnable task, T result)
- public interface Future<V> {
- boolean cancel(boolean mayInterruptIfRunning);
- boolean isCancelled();
- boolean isDone();
- V get() throws InterruptedException, ExecutionException;
- V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
- }
- public class FutureTask<V> implements RunnableFuture<V> {
FutureTask类实现了RunnableFuture接口,我们看一下RunnableFuture接口的实现:
- public interface RunnableFuture<V> extends Runnable, Future<V> {
- void run();
- }
下面我们再来看看FutureTask的方法执行示意图(方法和Future接口基本是一样的,这里就不过多描述了)
- public FutureTask(Callable<V> callable) {
- }
- public FutureTask(Runnable runnable, V result) {
- }
- package com.zejian.Executor;
- import java.util.concurrent.Callable;
- /**
- * @author zejian
- * @time 2016年3月15日 下午2:02:42
- * @decrition Callable接口实例
- */
- public class CallableDemo implements Callable<Integer> {
- private int sum;
- @Override
- public Integer call() throws Exception {
- System.out.println("Callable子线程开始计算啦!");
- Thread.sleep(2000);
- for(int i=0 ;i<5000;i++){
- sum=sum+i;
- }
- System.out.println("Callable子线程计算结束!");
- return sum;
- }
- }
Callable执行测试类如下:
- package com.zejian.Executor;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Future;
- /**
- * @author zejian
- * @time 2016年3月15日 下午2:05:43
- * @decrition callable执行测试类
- */
- public class CallableTest {
- public static void main(String[] args) {
- //创建线程池
- ExecutorService es = Executors.newSingleThreadExecutor();
- //创建Callable对象任务
- CallableDemo calTask=new CallableDemo();
- //提交任务并获取执行结果
- Future<Integer> future =es.submit(calTask);
- //关闭线程池
- es.shutdown();
- try {
- Thread.sleep(2000);
- System.out.println("主线程在执行其他任务");
- if(future.get()!=null){
- //输出获取到的结果
- System.out.println("future.get()-->"+future.get());
- }else{
- //输出获取到的结果
- System.out.println("future.get()未获取到结果");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("主线程在执行完成");
- }
- }
|
Callable子线程开始计算啦!
主线程在执行其他任务
Callable子线程计算结束!
future.get()-->12497500
主线程在执行完成
|
- package com.zejian.Executor;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Future;
- import java.util.concurrent.FutureTask;
- /**
- * @author zejian
- * @time 2016年3月15日 下午2:05:43
- * @decrition callable执行测试类
- */
- public class CallableTest {
- public static void main(String[] args) {
- // //创建线程池
- // ExecutorService es = Executors.newSingleThreadExecutor();
- // //创建Callable对象任务
- // CallableDemo calTask=new CallableDemo();
- // //提交任务并获取执行结果
- // Future<Integer> future =es.submit(calTask);
- // //关闭线程池
- // es.shutdown();
- //创建线程池
- ExecutorService es = Executors.newSingleThreadExecutor();
- //创建Callable对象任务
- CallableDemo calTask=new CallableDemo();
- //创建FutureTask
- FutureTask<Integer> futureTask=new FutureTask<>(calTask);
- //执行任务
- es.submit(futureTask);
- //关闭线程池
- es.shutdown();
- try {
- Thread.sleep(2000);
- System.out.println("主线程在执行其他任务");
- if(futureTask.get()!=null){
- //输出获取到的结果
- System.out.println("futureTask.get()-->"+futureTask.get());
- }else{
- //输出获取到的结果
- System.out.println("futureTask.get()未获取到结果");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("主线程在执行完成");
- }
- }
|
Callable子线程开始计算啦!
主线程在执行其他任务
Callable子线程计算结束!
futureTask.get()-->12497500
主线程在执行完成
|
Java多线程编程:Callable、Future和FutureTask浅析(多线程编程之四)的更多相关文章
- Java 并发编程——Callable+Future+FutureTask
Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...
- Java多线程编程:Callable、Future和FutureTask浅析
通过前面几篇的学习,我们知道创建线程的方式有两种,一种是实现Runnable接口,另一种是继承Thread,但是这两种方式都有个缺点,那就是在任务执行完成之后无法获取返回结果,那如果我们想要获取返回结 ...
- Java并发编程:ThreadPoolExecutor + Callable + Future(FutureTask) 探知线程的执行状况
如题 (总结要点) 使用ThreadPoolExecutor来创建线程,使用Callable + Future 来执行并探知线程执行情况: V get (long timeout, TimeUnit ...
- java 多线程:Callable接口;FutureTask类实现对象【Thread、Runnable、Callable三种方式实现多线程的区别】
Callable接口介绍: Java5开始,Java提供了Callable接口,像是Runnable接口的增强版,Callable接口提供了一个 call()方法可以作为线执行体. call()方法比 ...
- java 并发runable,callable,future,futureTask
转载自:http://www.cnblogs.com/dolphin0520/p/3949310.html package future_call; import java.util.concurre ...
- Callable、Future、FutureTask浅析
1.Callable<V>接口 Runnable接口 public interface Runnable { public abstract void run(); } Callable ...
- Java多线程的Callable, Future, FutureCallback
Callable可以看成是一个增强版的Runnable, 带返回结果, 需要通过Future或者FutureTask来提交任务或运行线程, 然后通过Future/FutureTask的get方法得到返 ...
- java.util.concuttent Callable Future详解
在传统的多线程实现方式中(继承Thread和实现Runnable)无法直接获取线程执行的返回结果,如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦. 从 ...
- Java多线程:Callable,Future,FutureTask
一.Future Future和Callable基本是成对出现的,Callable负责产生结果,Future负责获取结果. 1.Callable接口类似于Runnable,只是Runnable ...
随机推荐
- Rhythmk 学习 Hibernate 01 - maven 创建Hibernate 项目之 增删改查入门
1.环境: Maven :3.1.1 开发工具:Spring Tool Suite 数据库 : Mysql 5.6 2.项目文件结构 文件代码: 2.1 .pom.xml <project x ...
- FoxPro 数据库文件及记录命令
ADDTABLE 在当前数据库中添加一个自由表 APPEND 在表的末尾添加一个或多个新记录 APPEND FROM ARRAY 由数组添加记录到表中 APPEND FROM 从一个文件中读入记录,追 ...
- role是一个HTML5的属性
<form role="form"> role是一个HTML5的属性,role="form"告诉辅助设备(如屏幕阅读器)这个元素所扮演的角色是个表单 ...
- MyBatis 动态SQL注意事项
- linux 解析json
epel源 yum install jq ====================== [root@mhc NaHan-master]# curl 127.0.0.1:5000/v2/_catalog ...
- VS2015解决方案资源管理器空白,不显示内容
解决方法: 1.先关闭vs: 2.把C:/Users/<users name>/AppData/Local/Microsoft/VisualStudio/14.0/ComponentMod ...
- 利用WKWebView实现js与OC交互注意事项
最近在写一些关于wkwebview的一些代码,发现了几点心得,记录一下. 1.js调用OC 我是利用wkwebview进行的开发实现,主要代码有三部分 1.向config注入OC对象 [config. ...
- 23-python用BeautifulSoup用抓取a标签内所有数据
1.获取子标签: thr_msgs = soup.find_all('div',class_=re.compile('msg')) for i in thr_msgs: print(i) ...
- Ninject在.NET WebForm和MVC中的使用
1.建立项目:Models/BLL/DAL/IBLL/IDAL/WebSite 2.WebSite要引用其余几个项目 3.NuGet中搜索Ninject,安装 Ninject.Ninject.Web. ...
- MySQL之——GROUP BY分组取字段最大值
转载自:http://blog.csdn.net/l1028386804/article/details/54657412 假设有一个业务场景,需要查询用户登录记录信息,其中表结构如下: CREATE ...