【问题标题】:Exception in thread "main" java.lang.ClassCastException: cannot be cast to java.util.concurrent.Callable线程“主”java.lang.ClassCastException 中的异常:无法转换为 java.util.concurrent.Callable
【发布时间】:2016-08-16 22:44:25
【问题描述】:

我有一个整数数组,我想以多线程方式计算每个整数^2 的总和。我编写了程序,当我运行它时出现异常。 程序如下:

package ir.org.acm.multithreadpower;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class Main3 {
    public static volatile int[] a;
    public static int i = 0;
    public static Collection tasks=new ArrayList();
    public static int sum=0;

    static{
        int length=9;
        a=new int[length];
        for(int k=0;k<length;k++)
            a[k]=k;
    }
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(8);
        new Main3().doJob(executor);
        executor.invokeAll(tasks);
        System.out.println(sum);


    }
    public void doJob(ExecutorService executor) throws Exception{

        for(int m=0;m<(a.length);m++) {
            tasks.add(new Runnable() {
                @Override
                public void run() {
                    a[i] = a[i] * a[i];
                    i++;
                }
            });
       }

        for (int k = 0; k < a.length; k++)
            sum += k;

        executor.shutdown();

    }
}

程序抛出运行时异常:

Exception in thread "main" java.lang.ClassCastException: ir.org.acm.multithreadpower.Main3$2 cannot be cast to java.util.concurrent.Callable
    at java.util.concurrent.AbstractExecutorService.invokeAll(AbstractExecutorService.java:235)
    at ir.org.acm.multithreadpower.Main3.main(Main3.java:35)

我用谷歌搜索了这个问题,但无法弄清楚这个问题 感谢您的帮助。

问候,

【问题讨论】:

标签: java multithreading executorservice


【解决方案1】:

你的问题在这里:

public static Collection tasks=new ArrayList();

这是一个rawtype,这意味着编译器在使用这个Collection时无法保证安全。

怎么样,看Executor.invokeAll,签名是:

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)

所以你的Collection 需要包含Callable&lt;T&gt;T 无关紧要)。

现在,让我们看看你的代码:

public void doJob(ExecutorService executor) throws Exception {
    for(int m=0;m<(a.length);m++) {
        tasks.add(new Runnable() {
                    //^ here

所以你要添加Runnable。显然Runnable 不是 Callable

TL;DR:

变化:

public static Collection tasks = new ArrayList();

到:

public static Collection<Callable<Void>> tasks = new ArrayList<>();

那么您将需要修复许多编译器错误。


当您编译此代码时,您会收到如下警告:

[WARNING] ...App.java:[17,27] unchecked method invocation: method invokeAll in interface java.util.concurrent.ExecutorService is applied to given types
  required: java.util.Collection<? extends java.util.concurrent.Callable<T>>
  found: java.util.Collection
[WARNING] ...App.java:[17,28] unchecked conversion
  required: java.util.Collection<? extends java.util.concurrent.Callable<T>>
  found:    java.util.Collection

不要忽略编译器警告。

【讨论】:

    【解决方案2】:

    您还应该将 executor.shutdown(); 从方法 doJob 移到 executor.invokeAll(tasks);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2011-04-13
      • 2020-12-13
      相关资源
      最近更新 更多