- callable与runnable区别
返回值 | 不同接口 | |
---|---|---|
Callable | 有返回值 | call() |
Runnable | 无返回值 | run() |
- 使用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();
}
- 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;
}