2012-11-19 36 views
2

如果我有以下哑代码:while循环中的线程是否会给另一个相同类型的线程提供CPU时间?

public static void main(String[] args) { 
    TestRunnable test1 = new TestRunnable(); 
    TestRunnable test2 = new TestRunnable(); 
    Thread thread1 = new Thread(test1); 
    Thread thread2 = new Thread(test2); 
    thread1.start(); 
    thread2.start(); 
} 

public static class TestRunnable implements Runnable { 
    @Override 
    public void run() { 
    while(true) { 
     //bla bla 
    } 
    } 
} 

以我当前节目我具有类似的结构,即两个线程执行相同的运行()方法。但由于某些原因,只有线程1被给予CPU时间,即线程2从来没有机会运行。这是因为当线程1处于while循环时,线程2等待?

我不完全确定,如果一个线程在while循环中是“阻塞”其他线程?我会这么认为,但不是100%肯定的,所以很高兴知道是否有人能告诉我这里发生的事情。

编辑 好吧,试图再次做一个非常简单的例子,现在两个线程都获得CPU时间。然而,我的原始程序并非如此。必须是某个地方的错误。现在看看。感谢大家清理它,至少我得到了这些知识。

+0

为我运行'JavaSE-1.7'。你使用1.7还是1.6? –

回答

7

JVM无法保证它将暂停一个繁忙的线程,以便为其他线程提供一些CPU。

在繁忙循环中呼叫Thread.yield();,或者如果这不起作用,请致电Thread.sleep(100);,以便让其他线程有一些CPU。

+0

我确实有线程睡了5秒,甚至尝试了20秒,但线程2仍然不允许在它的while循环中,尽管两个线程运行相同的run()方法? – DSF

+0

JVM真正处理CPU使用情况吗?这不是总是给OS来处理吗? – thedan

+1

@Jatt我觉得很难相信。编辑您的问题,并在while循环中添加所有(相关)代码,以向我们展示您正在做的事情。 – Bohemian

0

实际的线程调度应该由OS而不是Java来处理。这意味着每个线程应该有相同的运行时间(尽管不是以可预测的顺序)。在你的例子中,每个线程都会旋转,并在它处于活动状态时不做任何事如果在while循环中执行System.out.println(this.toString()),则实际上可以看到发生这种情况。你应该看到每个线程都可以打印出来。

为什么你认为一个线程占主导地位?

+0

我认为这是因为,因为在while循环内执行任何内容之前,我已经打印出线程名称。对于while循环的每一次迭代,它都只是将线程1打印出来。 Thread2永远不会进入while循环,即使它们运行相同的run()方法。这是我没有得到的。你提供的答案正是我对它的工作原理的理解。但后来这让我很困惑 – DSF

0

操作系统负责调度线程。这在几年前已经改变了。它在不同的操作系统(Windows/Linux等)之间有所不同,它在很大程度上取决于CPU的数量和代码的运行。如果代码不包含一些等待功能,如Thread.yield()或监视器上的wait()方法的同步块,则CPU很可能会使线程长时间运行。
让一台具有多个CPU的机器可以提高应用程序的并行性,但是在线程的run()方法内写入代码不会让其他线程在多线程环境中运行,这是一种糟糕的编程。

1

在某些时候,现代操作系统将preempt当前上下文并切换到另一个线程 - 然而,它也(是一个相当愚蠢的事情总)打开CPU到烤面包机:这个小“忙循环”可能会计算一个校验和,并且让这个运行变慢会是一个耻辱!

出于这个原因,它常常手动建议sleep/yield - 甚至sleep(0) - 这将收率执行的线程的前OS决定采取控制。实际上,对于给定的空循环代码,当手动产生时,这将导致99%的CPU使用率变为0%的CPU使用率。 (实际数字将根据每个循环完成的“工作”而有所不同)


产生一个螺纹/上下文的最小时间变化的基础上OS和配置这就是为什么它并不总是希望得到 - 但随后再次Java和“实时”一般不要不要用同样的句子。

+0

有趣!我会记住这一点。谢谢 – DSF

相关问题