[英]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写入后半部分-希望它们的数组段位于不同的缓存行上,并且无需写入主内存以保持一致性); 如果线程在相同的内存段上运行,则尝试让它们在不同的时间这样做,以便在将最终结果刷新到主内存之前,它们可以在缓存中计算中间结果。
那么在您的情况下, method1
, method2
和method3
是否彼此独立? 如果是这样,则为每个方法使用不同的线程。 如果它们不是独立的,例如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.