Reputation: 65
use thread pool:
ExecutorService exec = Executors.newFixedThreadPool(5);
FutureTask<Integer> ft = new FutureTask<Integer>(() -> rpcMethod());
exec.submit(ft);
call run method:
FutureTask<Integer> ft = new FutureTask<Integer>(() -> rpcMethod());
ft.run()
I looked at the run method source code, as if it was a synchronous call, it seems that there is no new thread. The reason I have this problem is because I looked at the source code of Dubbo's RpcContext#asyncCall and found that it is directly using FutureTask#run.Here is some part of the code.
public <T> Future<T> asyncCall(Callable<T> callable) {
try {
try {
setAttachment(Constants.ASYNC_KEY, Boolean.TRUE.toString());
final T o = callable.call();
//local调用会直接返回结果.
if (o != null) {
FutureTask<T> f = new FutureTask<T>(new Callable<T>() {
public T call() throws Exception {
return o;
}
});
f.run();
return f;
} else {
}
Upvotes: 0
Views: 251
Reputation: 13
FutureTask is a implementation of Runnable.
the difference is
if you use exec.submit(ft); its async, executed in two different threads.
if you use ft.run(); its been executed in the same thread.
If there are any doubts, try this. I put getResult() in another method, so you have a more explicit call stack:
public class FutureExample {
private Callable<Long> call = new Callable<Long>() {
private Long getResult(){
return Thread.currentThread().getId();
}
@Override
public Long call() {
return getResult();
}
};
private Long callByRun() throws ExecutionException, InterruptedException {
FutureTask<Long> ft = new FutureTask<>(call);
ft.run();
return ft.get();
}
private Long callByExec() throws ExecutionException, InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(5);
FutureTask<Long> ft = new FutureTask<>(call);
pool.submit(ft);
Long result = ft.get();
pool.shutdown();
return result;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
Long mainThreadId = Thread.currentThread().getId();
System.out.println(String.format("main: %d callByRun %d", mainThreadId, new FutureExample().callByRun()));
System.out.println(String.format("main: %d callByExec %d", mainThreadId, new FutureExample().callByExec()));
}
}
Upvotes: 1