2014-11-24 90 views
0

我有一個算法來計算網格的東西看上去非常大致是這樣的:如何讓兩個線程執行兩個不同的循環或方法?

public class Main { 

    pass1 ; 
    pass2 ; 

    public static void main(String[] args) throws java.lang.Exception { 
     Function f = new Function(); 
     f.solve(pass1, pass2); 
    } 
} 

public class Function { 

    public void solve(pass1, pass2) { 
     method1(pass1, pass2); 
     method2(pass1, pass2); 
     method3(pass1, pass2); 
    } 
    method1(pass1, pass2) { 
     //parse grid 
     for (row = 0; row < numofrows; row++) { 
      for (col = 0; col < numofcols; col++) { 
       method4(stuff in here to pass); 
         } 
        } 
       } 
        method2(pass1, pass2) { 
     //parse grid 
     for (row = 0; row < numofrows; row++) { 
      for (col = 0; col < numofcols; col++) { 
       method4(stuff in here to pass); 
         } 
        } 
       } 
        method3(pass1, pass2) { 
     //do stuff 
    } 

    method4(stuff) { 
     //add object to hashmap 
    } 
} 

我想使算法快使用線程。

我的想法是讓一個線程使用偶數增量計數器執行method1和/或method2,另一個線程使用更多的cpu執行它,因爲現在它只使用25%(我認爲是1/4內核)。

如果我製作method2even()method2odd(),是否可以讓線程執行不同的循環或方法?如果是的話我將如何實現這一點,我一直在努力了幾個小時,我不能換我的頭周圍...

+0

將邏輯分成單獨的類,實現'Callable'接口併爲其執行... – MadProgrammer 2014-11-24 05:21:47

回答

1

什麼你所建議的是細粒度並行,這可能會導致因爲內存的問題層次結構 - 如果兩個線程在相同陣列/矩陣的交替索引上操作,那麼它們將不得不直接寫入主內存(例如,在每次操作後刷新它們的緩存),這可能會導致您的多線程程序比你的單線程程序運行速度慢得多。儘可能地嘗試讓你的線程寫入完全不同的內存段,例如完全不同的陣列/矩陣或相同的陣列/矩陣的至少不同的部分(例如,線程1寫入到陣列的前半部分,同時線程2寫入第二半 - 希望他們的陣列段將在不同的高速緩存行和它們不會需要寫入主內存以保持一致性);如果你的線程在同一個內存段上運行,那麼就試着在不同的時間讓它們這樣做,這樣他們就可以在緩存最終結果到主內存之前計算它們在緩存中的中間結果。

那麼在你的情況下,是method1,method2method3彼此獨立?如果是這樣,那麼爲每種方法使用不同的線程。如果他們不是獨立的,例如method1必須先於method2必須在method3之前,那麼您可以使用管道方式:Thread1對矩陣的前N個元素執行method1,然後Thread2對矩陣的前N個元素執行method2,而Thread1對第二個N元素執行method1的矩陣,則Thread3執行對矩陣的第一N個元素method3同時線程2的矩陣的第二N個元素執行method2而線程1執行method1在矩陣的第一N個元素,依此類推,直到所有的矩陣元素都已被處理。如果你的線程需要相互交流(例如傳遞矩陣段進行流水線處理),那麼我更喜歡使用類似BlockingQueue的東西:Method1和Method2將共享一個隊列,Method1將元素寫入它(通過offer )和Method2讀取元素(通過take)。與take直到方法一發送一條模具段上工作方法2塊,那麼當方法2已完成使模具段將在通過其他的BlockingQueue發送到方法3,然後將其與方法1股隊列再次呼籲take


假設你的方法是獨立的,那麼在獨立線程上運行它們的代碼如下:這可以修改以適應流水線。我省略了MethodN建設者在那裏你會需要在矩陣等我使用的是Runnable接口傳遞,但MadProgrammer在評論中說,你可以使用Callable代替。 ExecutorService負責將Runnables分配給線程。

public class Method1 implements Runnable { 
    public void run() { 
     // execute method1 
    } 
} 

public class Method2 implements Runnable { 
    public void run() { 
     // execute method2 
    } 
} 

public class Method3 implements Runnable { 
    public void run() { 
     // execute method3 
    } 
} 

public class Function { 
    private ExecutorService executor = Executors.newFixedThreadPool(3); 

    public void solve(pass1, pass2) { 
     Method1 method1 = new Method1(pass1, pass2); 
     Method2 method2 = new Method2(pass1, pass2); 
     Method3 method3 = new Method3(pass1, pass2); 
     executor.submit(method1); 
     executor.submit(method2); 
     executor.submit(method3); 
    } 
} 
相關問題