在Windows中,每个Java线程都映射到一个内核线程,而在Windows中,线程切换的时间片为10-100ms。
但是,从以下简单代码的结果来看,似乎每个线程每行代码都会切换CPU资源。为什么?
int male = 0;
int female = 0;
for (i = 0; i < size; i++) {
//if(A[i].IsMale()){male ++;}
//if(A[i].IsFemale()){female ++;}
//another way without boolean
male += A[i].GetMaleCount();
female += A[i].GetFemaleCount();
}
System.out.println("Male: "+male);
System.out.println("Female: "+female);
答案 0 :(得分:5)
首先,您不会告诉我们您看到的是什么以及期望看到的是什么。因此,无法解释前者,也无法解释后者为何会偏离基准。
但是,有许多因素可以解释为什么输出与您期望的不同。
输出可能取决于系统上的内核(或超线程)数量。以及操作系统可用于您的Java应用程序的数量。
如果在Java应用程序本身或系统的其他部分中运行着优先级更高的线程,则会干扰时间分片。 (如果需要安排高优先级线程,则可以将低优先级线程的时间片 缩短。)
由于时间分片,Java线程的重新调度不仅仅发生。当线程确实阻止I / O,或者尝试获取Lock
或互斥量,或wait(...)
或sleep(...)
或类似的东西时,也会发生这种情况。
System.out.println
在后台进行了一些隐藏的同步,因此,两个线程同时打印不会导致共享缓冲区数据结构的损坏。
简而言之,无论您从该程序中看到什么输出,都不会清晰证明时间分片行为。 (我的猜测是,这根本没有任何意义的证据。)
但是您问题的答案:
Java线程拥有CPU时间片多长时间?
是不可能预测的,并且很难测量。
答案 1 :(得分:2)
System.out.println
是一项阻塞操作,与您正在执行的其他所有操作相比,它需要花费大量时间。它还是同步的,因此一次只有一个线程可以打印一行。
这会导致您看到的交替行为。当一个线程正在打印时,另一个线程有足够的时间准备打印,调用println
,并等待第一个线程完成。当第一个线程完成打印后,第二个线程开始打印,第一个线程将返回,等待它完成之前。