2

i have an array of integers and i want to calculate sum of each integer^2 in multi thread way. i wrote the program and when i run it i get an exception. The program is as follows:

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();

    }
}

the program throws a run-time exception:

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)

i googled this issue but could not figure out this problem thanks for your help.

regards,

1

2 Answers 2

1

Your problem is here:

public static Collection tasks=new ArrayList();

This is a rawtype, which means the compiler cannot ensure safety when using this Collection.

How, lets look at Executor.invokeAll, the signature is:

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

So your Collection needs to contain Callable<T> (where T doesn't matter).

Now, lets look at your code:

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

So you are adding Runnable. Obviously Runnable is not Callable.

TL;DR:

Change:

public static Collection tasks = new ArrayList();

to:

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

then you'll have many compiler errors to fix.


When you compiled this code, you would have gotten a warning such as:

[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

don't ignore compiler warnings.

Sign up to request clarification or add additional context in comments.

Comments

0

You should also move executor.shutdown(); from the method doJob to after executor.invokeAll(tasks);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.