初识FutureTask

本文深入解析了FutureTask的原理,包括其关键属性、状态转换及核心方法,并提供了应用实例,展示了如何使用FutureTask来封装线程并获取异步计算结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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());
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值