多线程 FutureTask原理 & Callable接口

  1. callable与runnable区别
返回值不同接口
Callable有返回值call()
Runnable无返回值run()
  1. 使用example
FutureTask<MyObject> myFutureTask = new FutureTask<>(new Callable<MyObject>() {
	@Override
	public MyObject call() throws Exception {
		MyObject result = new MyObject();
		// execute business code
		return result;
	}
});

try {
	MyObject result = myFutureTask.get();
} catch (Exception e) {	
	e.printStackTrace();
}

  1. FutureTask原理
状态描述
NEW新建0
COMPLETING完成中1
NORMA正常2
EXCEPTIONAL异常3
CANCELLED取消4
INTERRUPTING中断中5
INTERRUPTED已中断6
 * Possible state transitions:
 * NEW -> COMPLETING -> NORMAL
 * NEW -> COMPLETING -> EXCEPTIONAL
 * NEW -> CANCELLED
 * NEW -> INTERRUPTING -> INTERRUPTED

在这里插入图片描述

3.1 构造函数

	/**
	* callable 入参,返回结果为override的call()方法的返回值
	*/
    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
    /**
    * runnable 入参,返回结果为入参中的result对象,线程执行runnable接口中的run方法。
    */
    public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }

3.2 返回值获取

	/**
	* 等待线程执行完,并且任务未取消,返回结果
	*/
    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L); //等待
        return report(s);
    }
	
	/**
	* 设置超时时间,超时抛出异常
	*/
	public V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        if (unit == null)
            throw new NullPointerException();
        int s = state;
        if (s <= COMPLETING &&
            (s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
            throw new TimeoutException();
        return report(s);
    }
	
	/**
	* 正常状态返回V,取消状态抛异常
	*/
	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);
    }

	/**
	* 状态等于1:thread.yield(); 
	* 状态大于1:返回状态s;
	* 超时返回当前状态s;
	* 抛出其他异常
	*/
    private int awaitDone(boolean timed, long nanos){
   		... ...
    }


3.3 线程run函数做的事
3.3.1 入参为callable
执行call(),并返回call()的返回值
3.3.2 入参为runnable、result
step1 : runnable被转换成 RunnableAdapter,RunnableAdapter实现了callable接口.
setp2 : call()调用了run()并返回result。
setp3 : FutureTask的run执行了RunnableAdapter的call()。

  static final class RunnableAdapter<T> implements Callable<T> {
        final Runnable task;
        final T result;
        RunnableAdapter(Runnable task, T result) {
            this.task = task;
            this.result = result;
        }
        public T call() {
            task.run();
            return result;
        }
    }

3.4 取消和中断
参数:mayInterruptIfRunning 是否需要中断。

  • 需要中断:
    尝试修改task状态为中断中;
    如果 修改成功,尝试中断线程;否则返回false;
    中断线程后,修改task状态为已中断;
    返回true;
    get()会获得 CancellationException;
  • 不需要中断:
    线程正常运行;
    尝试修改task状态为取消;
    修改成功返回true,否则返回false;
    get()会获得 CancellationException;
    public boolean cancel(boolean mayInterruptIfRunning) {
        if (!(state == NEW &&
              UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
                  mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
            return false;
        try {    // in case call to interrupt throws exception
            if (mayInterruptIfRunning) {
                try {
                    Thread t = runner;
                    if (t != null)
                        t.interrupt();
                } finally { // final state
                    UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
                }
            }
        } finally {
            finishCompletion();
        }
        return true;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值