一次可以在CPU上运行多少个线程?

15

我想知道在同一时间内,单个应用程序可以在CPU上运行多少个线程?

我的例子很简单:

import java.awt.SystemColor;
import java.util.Date;

public class Threadcall {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        System.out.println("--------------------------");
        System.out.println(Runtime.getRuntime().availableProcessors());
        System.out.println("--------------------------");
        for (int i = 0; i < 5; i++) {
            new samplethread(i);
        }
        // create a new thread
        //samplethread1.run();
        try {
            for (int i = 5; i > 0; i--) {
                System.out.println("Main Thread: " + i + "\t" + new Date());
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            System.out.println("Main thread interrupted.");
        }
        System.out.println("Main thread exiting.");
    }
}

public class samplethread implements Runnable {

    Thread t;

    samplethread(int i) {
        // Create a new, second thread
        t = new Thread(this, Integer.toString(i));
        System.out.println("Child thread Creation NO: " + i + "\t" + t.getName());



        t.start(); // Start the thread
        // t.run();

    }

    @Override
    public void run() {

        try {
            for (int i = 5; i > 0; i--) {

                System.out.println("Child Thread Run: " + i + "\t" + t.getName() + "\t" + new Date());
                // Let the thread sleep for a while.
                System.out.println("****************************");
                Thread.sleep(500);
            }
        } catch (InterruptedException e) {
            System.out.println("Child interrupted.");
        }
        System.out.println("Exiting child thread.");
    }
}

它显示的输出如下:

处理器数量:2

主线程:3 2013年5月26日星期日19:23:19 IST

子线程运行:1 2 2013年5月26日星期日19:23:19 IST

子线程运行:1 1 2013年5月26日星期日19:23:19 IST

子线程运行:1 3 2013年5月26日星期日19:23:19 IST

子线程运行:1 0 2013年5月26日星期日19:23:19 IST

子线程运行:1 4 2013年5月26日星期日19:23:19 IST

从输出中可以看出,同一时刻可以执行五个线程(我甚至将结果打印在毫秒级别)..........程序报告了我有两个处理器。

这是怎么可能的?

因为一个线程只能在一个CPU上运行,但它显示了同时运行五个线程。

有没有办法显示只有一个线程可以在一个CPU上运行......如果我修改代码如下:

t.start();
t.join();

然后它显示输出如下:
子线程创建编号: 99 99 子线程运行: 5 99 Sun May 26 21:02:32 IST 2013
子线程运行: 4 99 Sun May 26 21:02:32 IST 2013
子线程运行: 3 99 Sun May 26 21:02:33 IST 2013
子线程运行: 2 99 Sun May 26 21:02:33 IST 2013
子线程运行: 1 99 Sun May 26 21:02:34 IST 2013
那么,如果我在代码中添加一行简单的代码,如何可能只有两个线程可以访问两个处理器?

4
你可以显示到秒的时间。线程切换发生得更快,因此你在这里并没有注意到它。当你执行“sleep”时,线程不会占用CPU,可以自由地执行其他任务。 - Sergey Zyuzin
如果你所说的“CPU”是指“一个执行单元”,那么答案就是一个。然而,可以在一个执行单元上安排运行的线程数量可能会超过一个。 - fge
1
你的时间分辨率太小了。你应该以纳秒为单位打印结果。 - Christian Fries
2个回答

19

这取决于你对“同时”一词的理解。通过线程切换,即从一个线程执行一行代码,然后切换到另一个线程、执行一行代码,再切回来,你可以在同一处理器上执行无限数量的线程。处理器通过快速来回切换模拟“同时执行”的效果。

然而,大多数处理器在可执行真正的并发线程方面受到限制,即它们能够执行的线程数量与拥有的核心数相同,但这仍然是一个糟糕的估计,因为存在共享资源和硬件。理论上,你可以在4核处理器上运行最多4个同时线程。


2
每个线程也会消耗其堆栈的内存。在 Windows 上,默认情况下为 1 MB。因此,线程的数量也受可用内存的限制。 - Sergey Zyuzin
真实的,无限的,仅受机器和操作系统资源的限制。 - Jason
@jason 如果我修改我的代码如下:t.start(); t.join();那么它会显示输出如下:Child thread Creation NO: 99 99 Child Thread Run: 5 99 Sun May 26 21:02:32 IST 2013Child Thread Run: 4 99 Sun May 26 21:02:32 IST 2013Child Thread Run: 3 99 Sun May 26 21:02:33 IST 2013Child Thread Run: 2 99 Sun May 26 21:02:33 IST 2013Child Thread Run: 1 99 Sun May 26 21:02:34 IST 2013那么,如果我在代码中添加一行简单的语句,它怎么可能只允许两个线程访问两个处理器呢? - user900481

8
每个处理器都有一定数量的核心,每个核心可以同时运行一定数量的线程。例如:如果一个处理器有2个核心,每个核心可以同时处理4个线程,那么该处理器在任何给定的时刻可以运行4*2=8个线程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接