FutureTask

FutureTask是Future的实现,用来异步任务的获取结果,可以启动和取消异步任务,查询异步任务是否计算结束以及获取最终的异步任务的结果。通过get()方法来获取异步任务的结果,但是会阻塞当前线程直至异步任务执行结束。一旦任务执行结束,任务不能重新启动或取消,除非调用runAndReset()方法。

代码示例:

public class ThreadTest {

  public static void main(String[] args) throws Exception {

    Callable<String> myCallable = new MyCallableThread();
FutureTask<String> futureTask = new FutureTask<>(myCallable);
Thread myCallableThread = new Thread(futureTask);
myCallableThread.setName("MyThread-implements-Callable-test");
myCallableThread.start();
System.out.println("Run by Thread:" + futureTask.get()); //通过线程池执行
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(futureTask);
executorService.shutdown();
System.out.println("Run by ExecutorService:" + futureTask.get());
}
} class MyCallableThread implements Callable<String> { @Override
public String call() throws Exception {
return Thread.currentThread().getName();
}
}

实现一个自己的FutureTask

根据FutureTask核心原理,要实现一个FutureTask必须满足以下方面:

  • 需要泛型定义用以返回结果类型
  • 需要一个callable对象,在构造方法中传入
  • 需要实现runnable接口,在run方法中实现具体结果计算
  • 需要一个公开的get方法来获取结果
  • 如果线程没有执行完,则调用get方法的线程需要进入等待队列
  • 需要一个字段记录线程执行的状态
  • 需要一个等待队列存储等待结果的线程

代码示例:

/**
* 1. 泛型定义
* 2. 构造方法 callable
* 3. 实现了runnable
* 4. get方法返回callable执行结果
* 5. get方法有阻塞的效果(未执行结束的话)
*/
public class MyFutureTask<T> implements Runnable { // 程序执行的结果
private T result; // 要执行的任务
private Callable<T> callable; // 任务运行的状态
private volatile int state = NEW; // 任务运行的状态值
private static final int NEW = 0;
private static final int RUNNING = 1;
private static final int FINISHED = 2; // 获取结果的线程等待队列
LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>(100); // 执行当前FutureTask的线程,用CAS进行争抢
AtomicReference<Thread> runner = new AtomicReference<>(); public MyFutureTask(Callable<T> task) {
this.callable = task;
} @Override
public void run() {
// 判断当前对象的状态,如果是New且抢锁成功就执行
if (state != NEW || !runner.compareAndSet(null, Thread.currentThread())) return;
state = RUNNING;
try {
result = callable.call();
} catch (Exception e) {
e.printStackTrace();
} finally {
state = FINISHED;
} // 方法执行完,唤醒所有线程
while (true) {
Thread waiterThread = waiters.poll();
if (waiterThread == null) break;
LockSupport.unpark(waiterThread);
}
} public T get() {
// 如果状态不是FINISHED,则进入等待队列
if (state != FINISHED) {
waiters.offer(Thread.currentThread());
}
while (state != FINISHED) {
LockSupport.park();
}
return result;
}
} // MyFutureTask 测试
public class FutureTaskTest {
public static void main(String[] args) { Callable<String> myCallable = new MyCallableThread();
MyFutureTask<String> futureTask = new MyFutureTask<>(myCallable);
Thread myCallableThread = new Thread(futureTask);
myCallableThread.setName("MyFutureTask-test");
myCallableThread.start();
System.out.println("Run by Thread:" + futureTask.get());
}
} class MyCallableThread implements Callable<String> { @Override
public String call() throws Exception {
return Thread.currentThread().getName();
}
}

自定义FutureTask实现的更多相关文章

  1. Java FutureTask理解

    尊敬原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/8956703 FutureTask是为了弥补Thread的不足而设计的,它可以 ...

  2. [转载] java多线程学习-java.util.concurrent详解(二)Semaphore/FutureTask/Exchanger

    转载自http://janeky.iteye.com/blog/770393 ------------------------------------------------------------- ...

  3. java中Future与FutureTask使用与分析

    Future与FutureTask都是用于获取线程执行的返回结果.下面我们就对两者之间的关系与使用进行一个大致的介绍与分析 一.Future与FutureTask介绍: Future位于java.ut ...

  4. FutureTask简单实战

    FutureTask是什么? 线程池的实现核心之一是FutureTask.在提交任务时,用户实现的Callable实例task会被包装为FutureTask实例ftask:提交后任务异步执行,无需用户 ...

  5. 《java并发编程实战》读书笔记11--构建自定义的同步工具,条件队列,Condition,AQS

    第14章 构建自定义的同步工具 本章将介绍实现状态依赖性的各种选择,以及在使用平台提供的状态依赖机制时需要遵守的各项规则. 14.1 状态依赖性的管理 对于并发对象上依赖状态的方法,虽然有时候在前提条 ...

  6. Flume自定义拦截器(Interceptors)或自带拦截器时的一些经验技巧总结(图文详解)

    不多说,直接上干货! 一.自定义拦截器类型必须是:类全名$内部类名,其实就是内部类名称 如:zhouls.bigdata.MySearchAndReplaceInterceptor$Builder 二 ...

  7. SpringCache自定义过期时间及自动刷新

    背景前提 阅读说明(十分重要) 对于Cache和SpringCache原理不太清楚的朋友,可以看我之前写的文章:Springboot中的缓存Cache和CacheManager原理介绍 能关注Spri ...

  8. Java线程之FutureTask

    简述 FutureTask是Future接口的实现类,并提供了可取消的异步处理的功能,它包含了启动和取消(start and cancel)任务的方法,同时也包含了可以返回FutureTask状态(c ...

  9. 线程池续:你必须要知道的线程池submit()实现原理之FutureTask!

    前言 上一篇内容写了Java中线程池的实现原理及源码分析,说好的是实实在在的大满足,想通过一篇文章让大家对线程池有个透彻的了解,但是文章写完总觉得还缺点什么? 上篇文章只提到线程提交的execute( ...

随机推荐

  1. MacBook强制清除gardle缓存

    背景:在日常的工作开发中,为了方便维护一般采用gardle+Nexus的模式管理jar包,但方便的同时也会存在一些问题 例如:test-1.0.3.jar  jar包提供方修改了一些问题上传到Nexu ...

  2. 安装Eclipse for MAC 苹果版

    1. 安装Eclipse for MAC 苹果版 2. Thank you for downloading Eclipse If the download doesn't start in a few ...

  3. jQuery 文本框 光标 移动到 文字最后

    方法一:调用办法:setCaretToPos(document.getElementById("YOURINPUT"), 4); function setSelectionRang ...

  4. 【POJ - 1426】Find The Multiple(dfs)

    -->Find The Multiple 原文是英语,直接上中文了 Descriptions: 给定一个正整数n,请编写一个程序来寻找n的一个非零的倍数m,这个m应当在十进制表示时每一位上只包含 ...

  5. Leetcode 195 Tenth Line

    Given a text file file.txt, print just the 10th line of the file. Example: Assume that file.txt has ...

  6. python数据库-MongoDB的安装(53)

    一.NoSQL介绍 1.什么是NoSQL NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL". NoSQL,指的是非关系型的数据库.NoSQL有时也称 ...

  7. 20190716 NOIP模拟测试4 考试反思

    总分 127分 满分300 第一题 礼物 10分 一道期望题,看起来挺简单,但对于概率与期望这一块我还不怎么会,花了一个小时调他,最后只QJ了一下10%的测试点 第二题 通讯 90分 显然的缩点求解, ...

  8. Skyline WEB端开发2——添加一个定位点、文本标签

    Skyline 添加定位点 sgworld.Creator.CreatePosition CreatePosition( X, //兴趣点的东西方向坐标,即经度 Y, //兴趣点的南北方向坐标,即纬度 ...

  9. QRowTable表格控件(二)-红涨绿跌

    目录 一.开心一刻 二.概述 三.效果展示 四.任务需求 五.指定列排序 六.排序 七.列对其方式 八.相关文章 原文链接:QRowTable表格控件(二)-红涨绿跌 一.开心一刻 一天,五娃和六娃去 ...

  10. 并发,并行,线程,进程,GIL锁

    1.并发和并行 并发: 同时做某些事,但是强调同一时段做多件事 如:同一路口,发生了车辆要同时通过路面的时间. 并行: 互不干扰的在同一时刻做多件事 如:同一时刻,同时有多辆车在多条车道上跑,即同时发 ...