我写了一个简单的代码,它使用多个线程来计算从1到N的素数。
public static void main (String[] args) throws InterruptedException
{
Date start;
start = new Date();
long startms = start.getTime();
int number_primes = 0, number_threads =0;
number_primes = Integer.parseInt(args[0]);
number_threads = Integer.parseInt(args[1]);
MakeThread[] mt = new MakeThread[number_threads];
for(int i=1;i<=number_threads;i++)
{
mt[i-1] = new MakeThread(i,(i-1)*(number_primes/number_threads),i*(number_primes/number_threads));
mt[i-1].start();
}
for(int i=1;i<number_threads;i++)
{
mt[i-1].join();
}
Date end = new Date();
long endms = end.getTime();
System.out.println("Time taken = "+(endms-startms));
}
}
如上所示,我希望显示最终时间(仅测量不同输入的性能)。但是我注意到,当我输入一个非常大的N值并且只分配1或2个线程时,调度程序似乎会覆盖连接功能(即在其他线程结束之前显示最后一个print语句)。内核是否允许这样做?或者我的代码中有一些错误?
P.S:我只展示了我的部分代码。我在新分叉线程调用的函数末尾有一个类似的System.out.println。
答案 0 :(得分:1)
你的循环就是问题。
for(int i=1;i<number_threads;i++)
{
mt[i-1].join();
}
要么将条件更改为&lt; =,要么像这样做一个不那么神秘的循环:
for(int i=0; i < number_threads;i++){
mt[i].join();
}
或每个循环:
for(MakeThread thread : mt)
thread.join();
答案 1 :(得分:0)
如果您更正了在所有线程上调用join
的循环,如下所示
for(int i=0;i<number_threads;i++)
{
mt[i].join();
}
在所有线程(在循环中指定)完成运行并加入主线程之前,无法调用最后一个打印行。调度程序无法使用此语义进行任何假设。正如托马斯所指出的那样,你的代码中的错误是在最后一个线程上没有调用join
(因此在调用最后一个打印之前没有完成)。