2014-02-28 74 views
0

我理解fork/join的概念,但幾乎所有互聯網上的資源都使用Fibonacci作爲示例,但我的場景更復雜。我畫了程序,我有一個例外,在下面的代碼中評論。無法將java.util.concurrent.ForkJoinWorkerThread轉換爲java.lang.Thread-複雜結構

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

    } 

} 
} 
+0

[Javadoc中](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ForkJoinTask。在Fork方法中:「此方法只能在ForkJoinPool計算中調用(可以使用inForkJoinPool方法確定)。嘗試在其他上下文中調用會導致異常或錯誤,可能包括ClassCastException。 「你只能從'compute()'中調用的東西運行fork()。如果沒有真正理解你在做什麼,你的Train類應該既不是「作業控制器」,也不是作業的數據對象。 –

回答

1

我認爲你的問題是由於從主線程調用fork()。當您調用p.invoke(new Train())時,您的默認火車構造函數實際上會調用run_vec()並嘗試fork()。在閱讀javadocs時,有一些例子在compute()中調用fork()。您需要從p.invoke()啓動的線程調用fork。

0

基於這個Java文章我做了下面的代碼片段上:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/RecursiveAction.html

您應該只有一個「運行」線程中調用fork(重生)。這意味着必須將compute方法內的列車陣列上通過:

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

} 
} 
+0

請原諒我的雙重發帖。我仍然覺得有些代碼有助於澄清問題(從IT裂縫到IT裂縫)。 – Markus

+0

感謝您的回覆,但是這將會產生無限循環,因爲在run_Vec(t)中,您每次從train [i] = new Train(i * 4,i/2)創建一個新的構造函數。這意味着每次都從同一個類創建一個實例。 – Yasmin