初识FutureTask

FutureTask

什么是FutureTask?

FutureTask集成了RunnableFuture接口,能够封装runnable和callable线程,用线程池提交或者线程提交,获取线程异步计算的结果。

image

关键源码解析

关键属性

private volatile int state;
private static final int NEW          = 0;
private static final int COMPLETING   = 1;
private static final int NORMAL       = 2;
private static final int EXCEPTIONAL  = 3;
private static final int CANCELLED    = 4;
private static final int INTERRUPTING = 5;
private static final int INTERRUPTED  = 6;
  • NEW:未启动
  • COMPLETING:已启动
  • NORMAL:正常完成
  • EXCEPTIONAL:异常完成
  • CANCELLED:取消
  • INTERRUPTING:
  • INTERRUPTED:线程中断

关键的状态转换

  • NEW -> COMPLETING -> NORMAL
  • NEW -> COMPLETING -> EXCEPTIONAL
  • NEW -> CANCELLED
  • NEW -> INTERRUPTING -> INTERRUPTED

关键方法

  • get()方法
/**
 * @throws CancellationException {@inheritDoc}
 * 获取异步计算的结果
 */
public V get() throws InterruptedException, ExecutionException {
    int s = state;
    //如果线程刚启动,则等待线程执行完毕;如果线程已经执行完,则根据线程具体状态,判断是否获取结果
    if (s <= COMPLETING)
        s = awaitDone(false, 0L);
    return report(s);
}
  • awaitDone()方法
/**
* Awaits completion or aborts on interrupt or timeout.
*
* @param timed true if use timed waits
* @param nanos time to wait, if timed
* @return state upon completion
*/
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
//计算超时时间
final long deadline = timed ? System.nanoTime() + nanos : 0L;

//等待队列,这里就是一个单向链表
WaitNode q = null;
boolean queued = false;

//自旋等待线程执行完
for (;;) {
    if (Thread.interrupted()) {
        //如果线程中断了,移除等待队列中的当前节点
        removeWaiter(q);
        throw new InterruptedException();
    }

    int s = state;
    //当线程执行完后,直接返回当前状态
    if (s > COMPLETING) {
        if (q != null)
            q.thread = null;
        return s;
    }
    //当线程刚启动时,交出线程控制权
    else if (s == COMPLETING) // cannot time out yet
        Thread.yield();
    //当前节点为空时,新建一个节点
    else if (q == null)
        q = new WaitNode();
    else if (!queued)
        queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
                                             q.next = waiters, q);
    
    else if (timed) {
        nanos = deadline - System.nanoTime();
        if (nanos <= 0L) {
            removeWaiter(q);
            return state;
        }
        LockSupport.parkNanos(this, nanos);
    }
    else
        //阻塞,线程执行完后,set方法里会unpark
        LockSupport.park(this);
}
}
  • report()
/**
* Returns result or throws exception for completed task.
*
* @param s completed state value
*/
@SuppressWarnings("unchecked")
private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL)
    return (V)x;
if (s >= CANCELLED)
    throw new CancellationException();
throw new ExecutionException((Throwable)x);
}

FutureTask应用实例

/**
 *@author 
 *
 *类说明:如何新建线程
 */
public class NewThread {
	/*扩展自Thread类*/
	
	/*实现Runnable接口*/
	private static class UseRun implements Runnable{

		@Override
		public void run() {
			System.out.println("I am implements Runnable");
		}
		
	}
	
	/*实现Callable接口,允许有返回值*/
	private static class UseCall implements Callable<String>{

		@Override
		public String call() throws Exception {
			System.out.println("I am implements Callable");
			return "CallResult";
		}
		
	}	
	
	public static void main(String[] args) 
			throws InterruptedException, ExecutionException {
		//初始化测试线程
		UseRun useRun = new UseRun();
		new Thread(useRun).start();
		Thread t = new Thread(useRun);
		t.interrupt();
		
		UseCall useCall = new UseCall();
		FutureTask<String> futureTask = new FutureTask<>(useCall);
		//启动futureTask线程
		new Thread(futureTask).start();
		//输出线程计算结果
		System.out.println(futureTask.get());
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FutureTask是一个实现了RunnableFuture接口的类,它继承了Runnable和Future接口。因此,FutureTask既可以被当作一个Runnable来使用,也可以被当作一个Future来使用。 FutureTask实现了Future接口,完成了对Future接口的基本实现。除了实现了Future接口以外,FutureTask还实现了Runnable接口,这意味着它可以交由Executor执行,也可以直接用线程调用执行(futureTask.run())。 FutureTask具有三种执行状态:未启动、已启动和已完成。未启动指的是在调用run()方法之前,FutureTask处于未启动状态。已启动指的是FutureTask对象的run方法正在执行过程中,FutureTask处于已启动状态。已完成指的是FutureTask正常执行结束,或者被取消,或者执行过程中抛出异常而导致中断而结束。 在ThreadPoolExecutor的submit方法中,返回的是一个Future的实现,而这个实现就是FutureTask的一个具体实例。FutureTask帮助实现了具体的任务执行,并与Future接口中的get方法关联起来。 总结起来,FutureTask是一个能够同时担任Runnable和Future角色的类,它可以作为一个任务提交给线程池执行,也可以通过get方法来获取任务执行的结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【第十二篇】Java 线程池Future和FutureTask【重点】](https://blog.csdn.net/weixin_42039228/article/details/123198358)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [FutureTask简介](https://blog.csdn.net/u014516601/article/details/125123415)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值