线程自动交换进出,没有任何收益或睡眠

时间:2015-05-24 19:58:31

标签: java multithreading

当我们在run方法中编写类似yield,sleep之类的东西时,我认为一个线程只放弃了它的统治(控制?)。我希望看到的以下代码的输出类似于:

#1(5), #1(4), #1(3), #1(2), #1(1), #2(5), #2(4), #2(3), #2(2), #2(1), #3(5), #3(4), #3(3), #3(2), #3(1), #4(5), #4(4), #4(3), #4(2), #4(1), #5(5), #5(4), #5(3), #5(2), #5(1)
然而,事实证明所有线程都在同一时间运行。 输出:

#4(5), #2(5), #1(5), #1(4), #1(3), #1(2), #1(1), #3(5), #5(5), #3(4), #2(4), #2(
3), #4(4), #2(2), #3(3), #3(2), #5(4), #3(1), #2(1), #4(3), #4(2), #4(1), #5(3),
 #5(2), #5(1)

我很困惑。

public class SimpleThread extends Thread {
  private int countDown = 5;
  private static int threadCount = 0;
  public SimpleThread() {
    // Store the thread name:
    super(Integer.toString(++threadCount));
    start();
  }
  public String toString() {
    return "#" + getName() + "(" + countDown + "), ";
  }
  public void run() {
    while(true) {
      System.out.print(this);
      if(--countDown == 0)
        return;
    }
  }
  public static void main(String[] args) {
    for(int i = 0; i < 5; i++)
      new SimpleThread();
  }
}

3 个答案:

答案 0 :(得分:1)

  

当我们在run方法中编写类似yield,sleep等内容时,我认为一个线程只放弃了它的控制权(控制?)。

不,完全没有。线程并行运行,每个线程与所有其他线程并发执行。当您从多个线程同时打印到System.out时,通常会出现乱码输出。

自操作系统使用协作式多任务处理的Windows 3.x天以来,线程或进程无需明确控制权。 UNIX操作系统使用抢先式多任务处理,Windows 95以后的每个版本的Windows也是如此。抢先式多任务处理意味着操作系统可以在任何时候挂起线程,例如当它用完时间片时。

让线程并行运行使程序能够利用当今常见的多核架构。如果一次只能运行一个线程,那么拥有多个CPU就没有任何好处。

答案 1 :(得分:1)

根据规范,不保证线程执行顺序。因此,你不能指望在第二次启动之前完成启动的线程。

根据Kathy Sierra oca / ocp java se 7书(OCA / OCP Java SE 7程序员I&amp; II学习指南):

  

线程调度程序是JVM的一部分(尽管大多数JVM映射Java线程)   直接到底层操作系统上的本机线程,决定应该使用哪个线程   在任何给定时刻运行,并且还使线程退出运行状态。假设一个   单处理器机器,一次只能运行一个线程。只有一个堆栈   可以一次执行。它是线程调度程序决定哪个   所有符合条件的线程 - 实际上都会运行。当我们说合格时,我们真的   意味着处于可运行状态。   调度程序可以选择处于可运行状态的任何线程作为一个和   只运行线程。如果线程未处于可运行状态,则无法选择它   当前正在运行的线程。正因为如此,我们清楚地知道这里保证的程度如何:   无法保证选择运行可运行线程的顺序。   虽然队列行为是典型的,但不能保证。队列行为意味着   当一个线程完成其“转弯”时,它会移动到该线的末尾   可运行的池并等待它最终到达线的前面,它可以   再次被选中。实际上,我们将其称为可运行的池,而不是可运行的队列   有助于强化这样一个事实:线程并没有按照一定的保证顺序排列

答案 2 :(得分:0)

线程的运行方式主要取决于底层操作系统和硬件。操作系统决定您的线程何时执行以及执行顺序。

例如,如果您的计算机上有多个核心,操作系统可能会尝试同时运行您的线程(同时)。

即使您只有一个核心,操作系统也很可能会尝试公平,并为所有线程提供一些时间来执行,因为它们具有相同的优先级。