如何从Callable接口返回Future对象(executorService.submit的内部工作原理)

4

我试图理解在运行 executorService.submit(Callable); 时如何创建 future 对象。

例如,假设我创建了一个线程池,在其中传递了我的 callable 实现。

class FactorialCalculator implements Callable<Long> { 
  private int number; 
  public FactorialCalculator(int number) { 
    this.number = number; 
  } 
  @Override 
  public Long call() throws Exception { 
        return (number*number); 
  }
}

我想返回Future对象以便从调用函数中获取返回值。 我的自定义线程池类似于这样
class MyThreadPool implements java.util.concurrent.Executor 
{
    private final java.util.concurrent.BlockingQueue<Callable> queue;

    public MyThreadPool(int numThreads) {
        queue = new java.util.concurrent.LinkedBlockingQueue<>();
        for (int i=0 ; i<numThreads ; i++) {
            new Thread(new Runnable(){
                @Override
                public void run() {
                    while(true) {
                        queue.take().call();
                    }
                }
            }).start();
        }
    }

    @Override
    public void submit(Callable command) {
        queue.put(command);
    }
}

现在,如果我这样做:

MyThreadPool mypool = new MyThreadPool(10);
mypool.submit(new FactorialCalculator(10));

我想提交一个方法来返回Future对象,这样我就可以检查线程是否已经执行完毕并返回值。请问如何返回Future对象。

1个回答

5
最简单的方法是将您的可调用对象放入FutureTask中:
@Override
public <T> Future<T> submit(Callable<T> callable) {
    FutureTask<T> future = new FutureTask(callable);
    queue.put(future);
    return future;
}

当然,更加简单的解决方案是使用Executors.newFixedThreadPool而不是重新实现它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接