11

我对多线程很陌生,我正在做一个项目,我试图在我的 Java 程序中使用 4 个 CPU。我想做类似的事情

int numProcessors = Runtime.getRuntime().availableProcessors();
ExecutorService e = Executors.newFixedThreadPool(numProcessors);

这能保证每个 CPU 都有一个线程工作吗?在我创建线程的时候,系统不会很忙,但是之后的一段时间会非常忙。我认为操作系统会选择最不忙的 CPU 来创建线程,但是如果在创建时它们都不是特别忙,它是如何工作的呢?

此外,线程池服务应该重用线程,但是如果它看到另一个 CPU 上有更多的可用性,它会杀死线程并在那里生成一个新线程吗?

4

3 回答 3

2

不,它不能保证线程运行的位置

事实上,操作系统线程调度程序可以自由地在它认为合适的情况下迁移内核周围的线程(所以一行你可以在核心 0 上,下一行在核心 4 上)

您可以设置线程的亲和性,但这在 java 中不可用(AFAIK)

于 2012-12-13T18:32:55.887 回答
2

这能保证每个 CPU 都有一个线程工作吗?

如果您有四个需要同时执行的任务,您可以期望它们每个都有一个线程。在 HotSpot JVM 中,它会在创建池时创建 Thread 对象,这些对象是实际线程的代理。何时创建实际线程以及如何创建对您来说很重要。

在我创建线程的时候,系统不会很忙,但是之后的一段时间会非常忙。我认为操作系统会选择最不忙的 CPU 来创建线程,但是如果在创建时它们都不是特别忙,它是如何工作的呢?

线程由操作系统创建,并添加到要调度的线程列表中。

此外,线程池服务应该重用线程,但是如果它看到另一个 CPU 上有更多的可用性,它会杀死线程并在那里生成一个新线程吗?

Java 在这件事上没有发言权。操作系统决定。它不会杀死和重新启动线程。

线程不像您建议的那样与 CPU 绑定。操作系统根据需要运行的线程和空闲的 CPU 在 CPU 之间传递线程。

于 2012-12-13T18:33:08.827 回答
1

“如果它发现另一个 CPU 上有更多的可用性,它会杀死线程并在那里产生一个新的吗?”

无需杀死并生成另一个以使用可用的 CPU。线程是未绑定到特定 CPU 的内存对象,并且可以从一个 CPU 浮动到另一个 CPU。线程执行是这样一个循环:

  • Thread.start()将线程放入处理器队列
  • 当有可用处理器时,调度程序将处理器队列中的第一个线程放入处理器
  • 当线程阻塞在一个占用的锁上,或者正在等待 I/O 操作结束时,它会从处理器中取出并放入相应的队列中。当锁被释放或 I/O 操作完成时,线程将从该队列移回处理器队列。
  • 当线程在没有阻塞的情况下工作太长时间(依赖于 o/s 的时间,比如 50 毫秒),就会发生中断,调度程序会查看处理器队列中是否有线程。如果有,则将当前线程从处理器中取出并放在处理器队列的末尾,并将队列中的第一个线程放在处理器上。这样,长时间运行的线程也可以让其他线程执行。

结果,线程经常改变它们的状态,但这对程序员来说是透明的。线程的整个想法是线程是处理器的模型,比真正的处理器更方便。使用该模型,不必担心在处理器上映射线程,直到您真正需要为止。

于 2012-12-14T09:15:21.537 回答