Java-线程和CPU之间的关系

Java-线程和CPU之间的关系,java,multithreading,executorservice,threadpool,Java,Multithreading,Executorservice,Threadpool,我对多线程非常陌生,我正在从事一个项目,我试图在Java程序中使用4个CPU。我想做点像 int numProcessors = Runtime.getRuntime().availableProcessors(); ExecutorService e = Executors.newFixedThreadPool(numProcessors); 这能保证每个CPU有一个线程工作吗?在我创建线程的时候,系统不会很忙,但是在之后的一段时间它会非常忙。我认为操作系统会选择最不繁忙的CPU来创建线程,

我对多线程非常陌生,我正在从事一个项目,我试图在Java程序中使用4个CPU。我想做点像

int numProcessors = Runtime.getRuntime().availableProcessors();
ExecutorService e = Executors.newFixedThreadPool(numProcessors);
这能保证每个CPU有一个线程工作吗?在我创建线程的时候,系统不会很忙,但是在之后的一段时间它会非常忙。我认为操作系统会选择最不繁忙的CPU来创建线程,但是如果在创建线程时没有一个线程特别繁忙,那么它是如何工作的呢


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

不,它不会保证线程在哪里运行

事实上,OS线程调度程序可以根据需要自由地围绕核心迁移线程(因此,一行可以在核心0上,下一行可以在核心4上)

您可以设置线程的数量,但这在java直接(AFAIK)中不可用

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

如果您有四个任务需要同时执行,那么可以预期它们每个都有一个线程。在HotSpot JVM中,它创建线程对象,当您创建池时,它是实际线程的代理。创建实际线程的时间和方式对您来说很重要

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

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

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

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

线程没有按照您建议的方式绑定到CPU。操作系统根据需要运行的线程和空闲的CPU在CPU之间传递线程。

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

没有必要杀死和繁殖另一个来使用可用的CPU。线程是不绑定到特定CPU的内存对象,可以从一个CPU浮动到另一个CPU。线程执行是这样的循环:

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

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

您的操作系统执行线程调度,而不是Java。我真正关心的是,操作系统将在同一个CPU上实例化所有线程,然后因为它重用线程,所以它会将线程保留在那里,即使CPU被固定,而其他3个是空闲的。这可能吗?你可以强制操作系统这么做,但是默认情况下,它会给每个cpu,下一个可以运行的空闲线程。我明白了,谢谢你的更新。如果操作系统通过CPU传递线程,那么我认为这就回答了我的问题。在UNIX上监视此操作的最佳方法是什么?如果我使用
top
功能,我会看到多个Java进程正在运行吗?如果在top中按
1
,它会显示所有CPU。如果您只运行一个繁忙的线程,您将看到它四处移动,即使没有实际的理由这样做。事实上,如果你试图编写一个低延迟的应用程序,这是很烦人的,因为每次它移动时,线程都会发生延迟和减速。谢谢你的帮助,Peter!