单核Java线程运行时的双核CPU利用率

时间:2012-03-01 02:38:49

标签: java multithreading operating-system utilization

  

可能重复:
  Would a multithreaded Java application exploit a multi-core machine very well?

我的双核机器(Windows XP 32位环境)上有一个简单易懂的Java线程

public static void main(String[] strs) {

    long j  = 0;
    for(long i = 0; i<Long.MAX_VALUE; i++)
        j++;

    System.out.println(j);
    }

我的期望是它会坚持使用单个CPU来充分利用高速缓存(因为在循环中我们继续使用本地变量j运行,因此一个CPU工具将是100%而另一个将是相当多的闲。 令我惊讶的是,在线程启动后,两个CPU的使用率都在40%~60%左右,而一个CPU的利用率略高于另一个CPU。

我的问题是,是否有任何操作系统负载均衡机制在检测到不平衡时启动?在我的情况下,Windows操作系统可能发现一个CPU几乎达到100%而另一个几乎处于空闲状态,因此它会定期将线程重新安排到另一个CPU?

enter image description here

#EDIT1 我找到了一个可能的解释: http://siber.cankaya.edu.tr/ozdogan/OperatingSystems/ceng328/node130.html

3 个答案:

答案 0 :(得分:3)

当OS执行线程时,它会运行每个线程一段时间(比如10-20ms),然后保存线程的状态,并寻找其他线程来运行。

现在,尽管您在查看CPU利用率图表时可能会想到,操作系统实际上运行的程序比程序中的程序要多得多。有些线程运行UI循环,线程在I / O上等待,线程运行后台服务等。大多数线程花费大部分时间来阻止等待某些东西。

我之所以谈论这个,是因为从操作系统的角度来看,情况比它看起来更复杂。有很多线程在做很多事情,操作系统试图在它们之间切换。假设您想要实现一种启发式方法,如果一个线程最后一次耗尽其整个量程,那么操作系统将努力将其安排到同一个核心。操作系统需要跟踪并考虑更多信息,优化的成功可能取决于许多难以预测的因素。

此外,在实践中将线程关联到核心的好处通常可以忽略不计,因此操作系统不会尝试自动执行此操作。相反,他们公开了一个功能,允许开发人员明确说明特定线程应该与核心关联,然后操作系统将尊重该决定。

这似乎是一个合理的权衡:如果你的线程在关注核心时表现更好,那就请求操作系统这样做。但是,操作系统不会费心试图为你解决这个问题。

答案 1 :(得分:1)

正如你所提到的,操作系统会弹回线程。以下本机代码也如您所述。

int main( int argc, char** argv )
{
    while( true );
    return 0;
}

如果你看一下这个过程,它一直是25%(使用四核),但Windows 7的资源监视器显示4个核心中没有一个是100%的常数,即使核心0处于使用率高于其他人。

核心之间的cpu may share缓存,因此这种行为并不意味着没有使用缓存。

答案 2 :(得分:0)