为了更好地理解Java中的线程,我编写了以下代码
public class SimpleRunnableTest {
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
Thread t1 = new Thread(new TT1());
t1.start();
Thread t2 = new Thread(new TT2());
t2.start();
t2.join();
t1.join();
long end = System.currentTimeMillis();
System.out.println("end-start="+(end-start));
}
}
class TT1 implements Runnable {
public void run(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class TT2 implements Runnable {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
我的想法是,如果我在Thread.sleep(5000)
线程中按顺序运行Thread.sleep(1000)
和main
,则消耗的时间将为6 sec
,但由于我使用的是线程,因此只会在多核CPU机器上花费5 sec
,确实如此。但我的问题是:
为什么单核CPU机器上的结果仍为5 sec
?当然使用线程,但它不只是通过时分复用模拟线程吗?
我对时分复用的理解是:假设Thread.sleep(5000)
是任务A,Thread.sleep(1000)
是任务B,我们可以将它分解为:A1,A2,A3; B1,B2
顺序只是:A1,A2,A3,B1,B2
时分复用线程只是:A1,B1,A2,B2,A3
如果是的话,为什么第一个花费6秒,第二个花费6秒?
我是基地吗?
答案 0 :(得分:12)
结果是5而不是6,因为两个线程可以同时睡眠。通过调用Thread.sleep()
进入睡眠状态可让另一个线程运行,但剩余的睡眠间隔计时器会继续为两个线程进行滴答。
请注意,这仅适用于休眠(使用几乎为零的CPU),但不适用于做有用的工作:在这种情况下,单核非超线程CPU上的时序确实是附加的。例如,如果一个线程需要进行5秒钟的数字运算,而另一个线程需要进行第二次数字运算,那么两个线程的总时间将为6秒。
答案 1 :(得分:1)
通过调用Thread.sleep(sleeptime),线程表示它至少在“睡眠时间”毫秒内不需要CPU。
与此同时,可以执行另一个线程。