我正在实现一个层来包装第 3 方通信层。
我需要执行的合同是:
FutureTask<SomeData> send(Request request);
我的层有一个 onMessageReceived 方法,当响应到达时由第 3 方调用。
我为实现我的层而采取的方法如下:
我有一个可调用的,它等待一个超时条件:
interface MyCallable<T> extends Callable<T> {
void signal();
}
class CallableWithSignal<T> implements MyCallable<T> {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private long waitTime;
public CallableWithSignal(int waitTimeSeconds){
this.waitTime=waitTimeSeconds;
}
@Override
public T call() throws Exception {
lock.lock();
try {
boolean wasSignaled = condition.await(waitTime, TimeUnit.SECONDS);
if(wasSignaled)
return null;
System.out.println("throwing exeption");
throw new Exception("timeout");
} finally {
lock.unlock();
}
}
@Override
public void signal() {
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}
}
我还扩展了 FutureTask 以公开 set 方法,如下所示:
class MyFutureTask<V> extends FutureTask<V> {
private MyCallable<V> myCallable;
public MyFutureTask(MyCallable<V> r) { super(r); myCallable = r;}
@Override
public void set(V x) { super.set(x); }
@Override
public void setException(Throwable t) { super.setException(t); }
@Override
protected void done() {
super.done();
myCallable.signal();
}
}
任务完成后,我向可调用对象发出信号以停止它。
所以每次调用 send 时,我都会创建一个新的 MyFutureTask,使用 executor 运行它,将它保存在 map 中并返回它。
当 onMessageReceived 被调用时,我在地图中找到任务并使用 set 方法设置其结果。
这是一个好方法吗?
还有一个问题:在任务中移动执行器逻辑是否是一种好方法?我的意思是,为它创建一个启动方法,它将使用执行器运行任务。
请指教。