【问题标题】:How to return object from Callable()如何从 Callable() 返回对象
【发布时间】:2011-07-27 20:19:21
【问题描述】:

我正在尝试从 call() 返回一个二维数组,但遇到了一些问题。到目前为止我的代码是:

//this is the end of main   
Thread t1 = new Thread(new ArrayMultiplication(Array1, Array2, length));
t1.start(); 
}

    public int[][] call(int[][] answer)
    {       

    int[][] answer = new int[length][length]; 

    answer = multiplyArray(Array1, Array2, length); //off to another function which returns the answer to here  

    return answer;                                  
    }

此代码编译,这不返回我的数组。我确定我可能使用了错误的语法,但我找不到任何好的示例。

编辑:稍作改动

【问题讨论】:

  • 返回什么?长度从何而来? Array1 和 Array2 来自哪里?
  • 我很确定answer = multiplyArray(Array1, Array2, length,); 不会编译,因为有一个额外的,。您应该发布更多代码,因为我认为不可能在没有猜测的情况下在这里做出假设。
  • 什么是调用 call() 方法?

标签: java multithreading callable


【解决方案1】:

除了 Joseph Ottinger 的回答之外,要传递要在 Callable 的 call() 方法中使用的值,您可以使用闭包:

    public static Callable<Integer[][]> getMultiplierCallable(final int[][] xs,
            final int[][] ys, final int length) {
        return new Callable<Integer[][]>() {
            public Integer[][] call() throws Exception {
                Integer[][] answer = new Integer[length][length];
                answer = multiplyArray(xs, ys, length);
                return answer;
            }
        };
    }

    public static void main(final String[] args) throws ExecutionException,
            InterruptedException {
        final int[][] xs = {{1, 2}, {3, 4}};
        final int[][] ys = {{1, 2}, {3, 4}};
        final Callable<Integer[][]> callable = getMultiplierCallable(xs, ys, 2);
        final ExecutorService service = Executors.newFixedThreadPool(2);
        final Future<Integer[][]> result = service.submit(callable);
        final Integer[][] intArray = result.get();
        for (final Integer[] element : intArray) {
            System.out.println(Arrays.toString(element));
        }
    }

【讨论】:

  • 我要非常感谢 Joseph Ottinger 和 Marimuthu Madasamy。在你的帮助下,我最终到达了那里。
【解决方案2】:

除了 Joseph 的出色回答之外,请注意您的方法签名是 int[][] call(int[][])。如果您引用Callable javadoc,您会看到Callablecall() 方法不接受任何参数。所以你的方法是一个重载,而不是一个覆盖,所以不会被调用Callablecall()方法的任何东西调用。

【讨论】:

  • 嘿,谢谢。我认为显示正确的用法比试图弄清楚(稍微不完整的)示例代码中实际发生的事情更容易。
  • 正如德国人所说:“Da liegt der Hund begraben”——这就是问题所在。
【解决方案3】:

这里有一些代码演示了 Callable 接口的使用:

public class test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
    Callable callable = new Callable() {
        @Override
        public int[][] call() throws Exception {
            int[][] array = new int[5][];
            for (int i = 0; i < array.length; i++) {
                array[i] = new int[]{5 * i, 5 * i + 1, 5 * i + 2, 5 * i + 3};
            }

            return array;
        }
    };

    ExecutorService service = Executors.newFixedThreadPool(2);
    Future<int[][]> result = service.submit(callable);

    int[][] intArray = result.get();
    for (int i = 0; i < intArray.length; i++) {
        System.out.println(Arrays.toString(intArray[i]));
    }
}
}

它的作用是构造一个可以提交给执行器服务的对象。它与 Runnable 基本相同,只是它可以返回一个值;我们在这里所做的是创建一个带有两个线程的 ExecutorService,然后将此可调用对象提交给服务。

接下来发生的是result.get(),它会一直阻塞直到callable返回。

您可能不应该自己进行线程管理。

【讨论】:

  • 这非常有用,但是如何将对象发送到可调用对象呢?我需要向它发送两个数组。
  • 您可以在构造时传入它们,或者扩展 Callable 接口以使用实例本地数组。
  • 很好的答案,并感谢推广 ExecutorService 的使用。真的没有多少地方应该再次使用 Thread。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-07
  • 1970-01-01
  • 1970-01-01
  • 2020-08-14
  • 2011-03-26
  • 2015-12-15
  • 2016-11-20
相关资源
最近更新 更多