繁体   English   中英

如何使两个线程执行两个不同的循环或方法?

[英]How can I make two threads to do two different loops or methods?

我有一种算法可以大致计算出网格中的内容,如下所示:

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()发生,是否可以使线程执行不同的循环或方法? 如果是这样的话,我将如何实施呢?我已经尝试了好几个小时,但仍无法解决……

您所建议的是细粒度的并行性,这可能会由于内存层次结构而引起问题-如果两个线程在同一数组/矩阵的交替索引上进行操作,则它们实际上将必须直接写入主内存(例如,通过在每次操作后刷新其缓存),这可能会使多线程程序的运行速度比单线程程序慢得多。 尽可能使线程写入完全不同的内存段,例如,完全不同的数组/矩阵或同一数组/矩阵的至少不同部分(例如,线程1写入数组的前半部分,而线程2写入后半部分-希望它们的数组段位于不同的缓存行上,并且无需写入主内存以保持一致性); 如果线程在相同的内存段上运行,则尝试让它们在不同的时间这样做,以便在将最终结果刷新到主内存之前,它们可以在缓存中计算中间结果。

那么在您的情况下, method1method2method3是否彼此独立? 如果是这样,则为每个方法使用不同的线程。 如果它们不是独立的,例如method1必须在method2之前, method3必须在method3之前,那么您可以使用管道方法:Thread1在矩阵的前N个元素上执行method1 ,然后Thread2在矩阵的前N个元素上执行method2 ,而Thread1在矩阵的后N个元素上执行method1 ,然后Thread3在矩阵的前N个元素上执行method3 ,而Thread2在矩阵的后N个元素上执行method2 ,而Thread1在矩阵的前N个元素上执行method1 ,依此类推直到所有矩阵元素都已处理。

如果您的线程需要互相交谈(例如,传递矩阵段以进行流水线处理),则我更喜欢使用BlockingQueue之类的方法 :Method1和Method2将共享一个队列,其中Method1向其中写入元素(通过offer ),而Method2读取元件从它(通过take )。 与方法2块take ,直到方法1发送一条模具段上下工夫,那么当方法2已完成使模具段将在通过其他的BlockingQueue发送到方法3,然后调用take上它与方法1股队列一次。


假设您的方法是独立的,则一些代码可以在单独的线程上运行,如下所示; 可以对其进行修改以适应流水线。 我省略了需要在其中传递矩阵等的MethodN构造函数。我使用的是Runnable接口,但是正如MadProgrammer在评论中所说,您可以改用Callable ExecutorService负责将Runnable分配给线程。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM