2014-11-24 38 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); 
    } 
} 
相关问题