如果我有以下虚拟代码:
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
}
}
}
在我当前的程序中,我有一个类似的结构,即两个线程执行相同的Run()方法。但由于某种原因,只有线程1被给予CPU时间,即线程2永远不会有机会运行。这是因为当线程1在其while循环中时,线程2会等待吗?
我不确定,如果一个线程在while循环中,它是否“阻塞”其他线程?我会这么认为,但不是100%肯定所以如果有人能告诉我这里发生了什么事情会很高兴。
修改 好吧,只是尝试再次制作一个非常简单的例子,现在两个线程都获得了CPU时间。然而,在我的原始程序中并非如此。某处必须是某些bug。现在调查一下。感谢大家清理它,至少我掌握了这些知识。
答案 0 :(得分:7)
JVM无法保证它会暂停一个繁忙的线程,为其他线程提供一些CPU。
最好在繁忙的循环中调用Thread.yield();
,或者如果调用Thread.sleep(100);
不起作用,让其他线程拥有一些CPU。
答案 1 :(得分:1)
在某些时候,现代操作系统将preempt当前上下文并切换到另一个线程 - 但是,它 (也是一个相当愚蠢的东西)将CPU转换为烤面包机:这个小的“忙碌循环”可能会计算一个校验和,让这个运行缓慢是一种耻辱!
出于这个原因,通常建议sleep/yield
手动 - 甚至sleep(0)
1 - 这将产生执行线程之前操作系统决定接受控制。实际上,对于给定的空循环代码,这将导致在手动屈服时从99%的CPU使用率变为0%的CPU使用率。 (实际数字将根据每个循环完成的“工作”等而有所不同。)
1 产生线程/上下文的最短时间因操作系统和配置而异,这就是为什么并不总是希望产生 - 但是Java和“实时”通常都要不会用同一句话。
答案 2 :(得分:0)
实际的线程调度应该由OS而不是Java来处理。这意味着每个线程应该被赋予相同的运行时间(尽管不是以可预测的顺序)。在您的示例中,每个线程在旋转时都会旋转并且不执行任何操作。如果你在while循环中System.out.println(this.toString())
,你实际上可以看到这种情况。您应该看到每个线程尽可能打印出来。
为什么你认为一个线程占主导地位?
答案 3 :(得分:0)
操作系统负责安排线程。这在几年前发生了变化。它在不同的操作系统(Windows / Linux等)之间有所不同,它在很大程度上取决于CPU的数量和运行的代码。如果代码不包含某些等待功能,如Thread.yield()或者在监视器上使用wait()方法的同步块,那么CPU可能会使线程长时间保持运行。
拥有一台具有多个CPU的计算机将提高应用程序的并行性,但在线程的run()方法中编写代码是一个糟糕的编程,不允许其他线程在多线程环境中运行。