public class DubboInvoker{
Result doInvoke(Invocation inv){
// 源码中108行
return currentClient
.request(inv, timeout)
.get();
}
}
//DefaultFuture类
// 创建锁与条件变量
private final Lock lock = new ReentrantLock();
private final Condition done = lock.newCondition();
// 调用方通过该方法等待结果
Object get(int timeout) {
long start = System.nanoTime();
lock.lock();
try {
while (!isDone()) {
done.await(timeout);
long cur = System.nanoTime();
if (isDone() ||
cur - start > timeout) {
break;
}
}
} finally {
lock.unlock();
}
if (!isDone()) {
throw new TimeoutException();
}
return returnFromResponse();
}
// RPC结果是否已经返回
boolean isDone() {
return response != null;
}
// RPC结果返回时调用该方法
private void doReceived(Response res) {
lock.lock();
try {
response = res;
if (done != null) {
done.signal();
}
} finally {
lock.unlock();
}
}
调用线程通过调用 get() 方法等待 RPC 返回结果,调用 lock() 获取锁,在 finally 里面调用 unlock() 释放锁;获取锁后,通过在循环中调用 await() 方法来实现等待。当 RPC 结果返回时,会调用 doReceived() 方法,这个方法里面,调用 lock() 获取锁,在 finally 里面调用 unlock() 释放锁,获取锁后通过调用 signal() 来通知调用线程,结果已经返回,不用继续等待了。
结合其思想,引用到某些业务情景中:如业务系统---平台---第三方,就可能遇到第三方提供的接口是异步或同步的,如果是平台针对业务系统就可以考虑封装成一个同步接口,让异步对下游的业务无感应。
单机时可简单设计:
集群可考虑如下: