2016-09-28 192 views
0

我正在研究一種新的NLP分類器算法,並希望使其成爲多線程。我的實現執行它應該正確執行的操作,但在運行threads = 4時出現一些奇怪的異常。 這是我的方法:Java產卵幽靈線程

protected void generateCoordinatesMultiThread(Category generate, int threads){ 
    WordMap wordMap = new WordMap(); 
    wordOccurences = new int[semanticspace.getVectorAmount()][generate.getSize()]; 
    tfidf = new double[semanticspace.getVectorAmount()][generate.getSize()]; 
    ntfidf = new double[semanticspace.getVectorAmount()][generate.getSize()]; 
    Thread[] threadGroup = new Thread[threads]; 
    try{ 
     System.out.println(generate.getSize()+" objects in "+threads+" threads"); 
     for(int i=0;i<threads;i++){ 
      int start=(generate.getSize()/threads)*i; 
      int end=((generate.getSize()/threads)*(i+1))-1; 
      if(i==threads-1){ 
       end=generate.getSize(); 
      } 
      System.out.println("Start: "+start+" end: "+end); 
      threadGroup[i] = new Thread(new WordMapper(this,start,end,generate,"WordMapper-"+i,wordMap)); 
      threadGroup[i].start(); 
     } 
     for(int i=0;i<threads;i++){ 
      threadGroup[i].join(); 
     } 
     System.out.println("First multi-thread step finished"); 
     wordMap.mapSemanticSpace(semanticspace); 
     wordMap.print(); 
    }catch(Exception e){ 
     System.out.println(e.getMessage()); 
    } 
    System.out.println("Starting frequency workers"); 
    threadGroup = new Thread[threads]; 
    try{ 
     System.out.println(generate.getSize()+" objects in "+threads+" threads"); 
     for(int i=0;i<threads;i++){ 
      int start=(generate.getSize()/threads)*i; 
      int end=((generate.getSize()/threads)*(i+1))-1; 
      if(i==threads-1){ 
       end=generate.getSize(); 
      } 
      System.out.println("Start: "+start+" end: "+end); 
      threadGroup[i] = new Thread(new FrequencyWorker(this,start,end,generate,"FrequencyWorker-"+i,wordMap)); 
      threadGroup[i].start(); 
     } 
     for(int i=0;i<threads;i++){ 
      threadGroup[i].join(); 
     } 
     System.out.println("Second multi-thread step finished"); 
    }catch(Exception e){ 
     System.out.println(e.getMessage()); 
    } 
    System.out.println("Starting coordinate generators"); 
    threadGroup = new Thread[threads]; 
    try{ 
     System.out.println(generate.getSize()+" objects in "+threads+" threads"); 
     for(int i=0;i<threads;i++){ 
      int start=(generate.getSize()/threads)*i; 
      int end=((generate.getSize()/threads)*(i+1))-1; 
      if(i==threads-1){ 
       end=generate.getSize(); 
      } 
      System.out.println("Start: "+start+" end: "+end); 
      threadGroup[i] = new Thread(new CoordinateGenerator(this,start,end,generate,"FrequencyWorker-"+i,wordMap)); 
      threadGroup[i].start(); 
     } 
     for(int i=0;i<threads;i++){ 
      threadGroup[i].join(); 
     } 
     System.out.println("Third multi-thread step finished"); 
    }catch(Exception e){ 
     System.out.println(e.getMessage()); 
    } 
} 

這讓我異常:在線程

異常 「主題-5」 顯示java.lang.NullPointerException

在semanticobjects.WordMapper.run(WordMapper的.java:21)

在java.lang.Thread.run(Thread.java:695)

與9和13相同。這兩個數字在運行線程數= 4時不應該首先生成。結果計算也是正確的。我只是得到這個例外。有什麼想法嗎?

+0

請指出whith行引發異常 - 標記'WordMapper.java:21' – Antoniossss

+0

是什麼讓您認爲theads是虛線?如果是線程號,請注意這個數字只是一個增加的靜態int,例如,如果您重新運行該方法,數字會更大(並且線程1可能是主線程,所以應該將4個新線程命名爲Thread -2到Thread-5)。如果您希望線程在調用該方法時具有相同的名稱,請爲該構造函數提供一個名稱。 – Thomas

+1

@SirTobiSwobi,但說實話,使用ExecutorService和Callable任務會更簡單。 – Antoniossss

回答

0

從Java 5開始,有一個新的(不是很新的)包:java.util.concurrent。在這個包中有很多工具可以讓你在使用多線程時變得簡單。特別是有幾個選項可以獲得開箱即用的線程池。請看Executors class API和ExecutorService class API。閱讀可用的ExecutorService的各種實現。它需要一些習慣,但是一旦你掌握了這個概念,就會消除線程管理的所有繁瑣工作,而你所要做的就是擔心你的實現邏輯。它也使你的代碼更簡單,更清潔。

0

如果你將尋找到Thread.class你會看到下面的代碼:

public Thread(ThreadGroup group, Runnable target) { 
      init(group, target, "Thread-" + nextThreadNum(), 0); 
    } 

    /* For autonumbering anonymous threads. */ 
    private static int threadInitNumber; 
    private static synchronized int nextThreadNum() { 
     return threadInitNumber++; 
    } 

因此,大家可以看到,每次你創建新的線程,它有一個使用靜態字段threadInitNumber創造的唯一名稱 - 記住靜態字段在給定類的所有實例中共享。

你的threadCount=4意味着你將一次創建4個線程,但你做了幾次,3次是準確的,3次4次等於12次 - 這就是在你看來創建「鬼」線程的原因。您正在創建12個線程而不是4個,但不是一次。現在爲什麼thre線程被命名爲13,保證12?那麼因爲其他應用程序必須在調用之前創建了新線程generateCoordinatesMultiThread