Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这是使用Java FutureTask&Callable的正确方法吗?_Java_Futuretask - Fatal编程技术网

这是使用Java FutureTask&Callable的正确方法吗?

这是使用Java FutureTask&Callable的正确方法吗?,java,futuretask,Java,Futuretask,我正在实现一个层来包装第三方通信层 我需要执行的合同是: FutureTask<SomeData> send(Request request); 我的层有一个onMessageReceived方法,当响应到达时,第三方会调用该方法 我采用的实现我的层的方法如下: 我有一个callable,它在超时的条件下等待: interface MyCallable<T> extends Callable<T> { void signal(); } class

我正在实现一个层来包装第三方通信层

我需要执行的合同是:

FutureTask<SomeData> send(Request request);
我的层有一个onMessageReceived方法,当响应到达时,第三方会调用该方法

我采用的实现我的层的方法如下:

我有一个callable,它在超时的条件下等待:

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,使用执行器运行它,将它保存在映射中并返回它

调用onMessageReceived时,我在映射中找到任务,并使用set方法设置其结果

这是一个好方法吗

还有一个问题:在任务中移动执行器逻辑是一种好方法吗?我的意思是,为它创建一个start方法,它将使用executor运行任务

请给我一些建议