0

I understand the concept of fork/join, but almost all resources over the internet use, Fibonacci as an example, but my scenario is more complex. I sketched the program, and I have an exception as commented in the below code..

Class Test
{

  public static void main(String[] args) 
{

    ForkJoinPool p= new ForkJoinPool(5);
    p.invoke(new Train());
}
}


Class Train extends RecursiveAction
{
public Train(int d, int n)
{
    //some intialization
}
public Train()
{
    t= new Train[5];
    new Vec().run_Vec(t);
}
@Override
protected void compute() {

        for(int i= 1; i< 8; i++)
        {
            // x, and y are predefined
            temp[x][y] = some calculation;

        }

}

}
class Vec
{
    public void run_Vec(Train[] t) {

        for (int i = 0; i < 5; i++) {
            t[i] = new Train(i*4, i/2);
            t[i].fork(); // error java.lang.Thread cannot be cast to   java.util.concurrent.ForkJoinWorkerThread
            }
        for (int i = 0; i < 5; i++) {

            t[i].join();
        }

    }

}
}
1
  • Javadoc on the Fork method: "This method may be invoked only from within ForkJoinPool computations (as may be determined using method inForkJoinPool). Attempts to invoke in other contexts result in exceptions or errors, possibly including ClassCastException." You can only run fork() from something called within your compute(). Without really understanding what you are doing, your Train class should not be both the "job controller" and also the data object for the job. Commented Feb 28, 2014 at 16:29

2 Answers 2

1

I think your problem is due to calling fork() from the main thread. When you call p.invoke(new Train()), your default train constructor actually calls the run_vec() and tries to fork(). Upon reading the javadocs, there are examples that fork() is called within compute(). You need to be calling fork from a thread started by p.invoke().

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

Comments

0

Based on this Java article I made the following code snippet: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/RecursiveAction.html

You should only call fork (spawn) within a "running" Thread. This means you must pass on the Train array within the compute method:

package ...;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

class ConcurrentTest {

public static void main(String[] args) {
    ForkJoinPool p= new ForkJoinPool(5);
    p.invoke(new Train());
}


public static class Train extends RecursiveAction {
    private Train[] t = null;
    public Train(int d, int n) {
        //some code
    }

    public Train() {
        t= new Train[5];
    }

    @Override
    protected void compute() {
        if(t != null) {
            new Vec().run_Vec(t);
            for(int i= 1; i< 8; i++) {
                System.out.println("Test.Train.compute(): " + i);   
            }
        }
    }
}


public static class Vec
{
    public void run_Vec(Train[] t) {
        for (int i = 0; i < 5; i++) {
            t[i] = new Train(i*4, i/2);
            System.out.println("Clazz: " + t[i].getClass());
            t[i].fork(); // error java.lang.Thread cannot be cast to   java.util.concurrent.ForkJoinWorkerThread
        }
        for (int i = 0; i < 5; i++) {
            t[i].join();
        }
    }

}
}

2 Comments

Please excuse my double posting. I am still under the impression that some code helps to clarify the issue (From IT cracks to IT cracks).
Thanks for your reply, but this will have an infinite loop because in run_Vec(t) you are creating a new constructor from Train each time t[i] = new Train(i*4, i/2); which means each time, create an instance from the same class..

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.