Java线程不是异步运行 - 有些根本没有完成

时间:2014-02-18 14:58:23

标签: java multithreading

我正在尝试完成大学项目的实验。我想并行运行它,利用多个核心,这样我就可以增加样本量。为了实现这一点,我创建了多个(最多7个,但我尝试使用少至2个)java线程并在所有这些线程中同时执行我的类。我的电脑有8个核心。

我遇到的问题是Java似乎对这些线程的执行方式是偶然的。所有7个线程都开始正常。它们异步运行一段时间。在一次典型的比赛中,其中3场比赛将在预期时间内完成,第4场比赛可能会在几分钟后结束,最后3场比赛完全没有结束。

实验课程设计为运行一定量的挂钟时间(不是cpu-clock时间)。这个因素超出了我的控制范围。所以我需要我的线程始终在不同的核心上同时运行。

以下代码段展示了我用来创建线程并启动它们的方法。它显然没有调用我正在用于我的实验的课程,如果你复制它并自己运行它,你会发现它工作正常。我在这里提供它只是为了证明我正在创建和正确使用线程。我好几天都在寻找答案,看不出我做错了什么。

这是一个测试类,展示了我的实验课使用的方法。它只是连接一些字符串数据,以确保足够长的运行过程。

public class ThreadTestClass implements Runnable {

@Override
public void run() {
    Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    System.out.println("This thread is underway");
    int i=0;
    String a="a";
    while(i<25){
        a=a+a;
        i++;
    }
    System.out.println("This thread ran fine");

}

}

这就是它的名称:

   private static void ThreatTestMethod(){
    Thread[] threads = new Thread[7];
    int i=0;

    while(i<threads.length){
        threads[i] = new Thread(new ThreadTestClass());
        threads[i].start();
        i++;
    }

    while(threads[0].isAlive() || threads[1].isAlive() || threads[2].isAlive() || threads[3].isAlive() || threads[4].isAlive() || threads[5].isAlive() || threads[6].isAlive()){
        try {
            Thread.sleep(5000);
        }
        catch (InterruptedException e) {
            System.out.println("Interrupted Exception Occurred");
        }
    }

}

我的理解是Java应该自动利用所有核心,并且当我执行我的线程时,它们应该利用所有可用的核心。这通常会发生什么。我运行实验时没有发生这种情况。有什么办法可以强制线程在不同的内核上同时运行吗?

3 个答案:

答案 0 :(得分:3)

您的示例代码很好。

如果你的某些线程没有返回,它们要么阻塞(例如在read(),write(),wait()上),要么它们被卡在循环中;就像任何其他不返回的程序一样。附加调试器,或只是获取堆栈跟踪转储,以找出他们正在做什么。

Java API无法指定如何将线程分配给核心。它依赖于实现,取决于Java实现和操作系统。

然而在实践中,你会发现只要你有一个合理的最新Java,线程就会在核心之间传播。

答案 1 :(得分:1)

简而言之 - 不。

有多个因素会影响可用处理器上不同任务和线程的调度。最明显的可能是JVM,硬件和您运行的实际调度程序。没有简单的方法可以强制执行此操作或保证在不同的核心上运行每个线程。

但是,可能有不同的方法使它们更有可能最终会出现在不同的核心上,但我认为你可能已经到了线程的终点。

答案 2 :(得分:0)

你的字符串连接是微不足道的 - 几乎是无操作。

您的线程可能会将大部分时间用在System.Out I / O锁上,因此根本不会运行。

如果您要开始创建线程,请给他们一些合理的工作。