Runable与Callable都是接口:
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface Runnable
is used
* to create a thread, starting the thread causes the object's
* run
method to be called in that separately executing
* thread.
*
* The general contract of the method run
is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
通过注释我们可以看出Callable中的call方法有返回值并且会抛出异常。
关于这个返回值怎么获取,以及这个异常怎么catch:
返回值:
首先我们看看这个方法在哪里被调用
去这个FutureTask看看
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
其中有几行重要的代码:
1.说明我们往FutureTask中塞了Callable
Callable<V> c = callable;
2.调用了call()方法
V result;
result = c.call();
3.将执行结果set到某处
set(result);
以上的1什么时候执行的呢
我们看看FutureTask的构造器:
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
这里正好可以传入一个callable,那么这个构造器什么时候执行的呢,我们可能是new了一个FutureTask或者FutureTask的子类
排除其他的,最像的可能就是这个AbstractExecutorService了
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
有个submit方法,它是实现了ExecutorService中的 Future submit(Runnable task, T result);
并且有个ThreadPoolExecutor实现类:
这个ThreadPoolExecutor不是抽象类,可以直接new
异常怎么catch:
call()会抛出异常,那么他的调用方run()也会抛出异常或者catch,
结果我们发现在run里面是catch了的:
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
protected void setException(Throwable t) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = t;
UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
finishCompletion();
}
}
在没有异常时,outcome就是执行结果,有异常就是Throwable子类
在get方法中就可以获取返回值了:
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}
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);
}
于是,就有了下面这个demo:
public class CallableDemo1 {
public static void main(String[] args) {
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 0
, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), threadFactory);
Future<String> future = threadPoolExecutor.submit(new MyCallable());
try {
System.out.println(future.get());
} catch (Exception e) {
e.printStackTrace();
} finally {
Thread.currentThread().interrupt();
}
System.out.println("程序结束");
while (true) {
if (Thread.currentThread().isInterrupted()) {
threadPoolExecutor.shutdown();
break;
}
}
}
}
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("程序正在执行");
Thread.sleep(5000);
return "程序执行成功";
}
}