Scheduler是否可以覆盖连接功能?

时间:2011-08-20 18:22:51

标签: java multithreading

我写了一个简单的代码,它使用多个线程来计算从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。

2 个答案:

答案 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(因此在调用最后一个打印之前没有完成)。